From 901ab6d7c9fbca7920f0125cafe78dd8d78f2b60 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 13 Feb 2012 16:31:11 +0100 Subject: [PATCH] Imported Upstream version 0.4.5+svn3915~dfsg0 --- Makefile | 5 + applications/mp4box/main.c | 2 +- applications/mp4box_android/.classpath | 7 - applications/mp4box_android/.project | 33 - .../mp4box_android/AndroidManifest.xml | 16 - .../mp4box_android/default.properties | 11 - .../mp4box_android/gen/org/enst/mp4box/R.java | 30 - applications/mp4box_android/proguard.cfg | 36 - .../mp4box_android/res/drawable-hdpi/icon.png | Bin 4147 -> 0 bytes .../mp4box_android/res/drawable-ldpi/icon.png | Bin 1723 -> 0 bytes .../mp4box_android/res/drawable-mdpi/icon.png | Bin 2574 -> 0 bytes .../mp4box_android/res/layout/main.xml | 10 - .../mp4box_android/res/values/strings.xml | 7 - .../src/com/enst/mp4box/mp4box.java | 129 - .../src/com/enst/mp4box/mp4terminal.java | 7 - applications/osmo4_ios/Resources/icon.png | Bin 7682 -> 0 bytes applications/osmo4_ios/Resources/osmo.icns | Bin 147235 -> 0 bytes applications/osmo4_ios/extract.c | 702 ----- applications/osmo4_ios/main.c | 2117 --------------- applications/osmo4_ios/osmo4ios-Info.plist | 24 - applications/osmo4_wx/Darwin.Info.plist | 32 - .../osmo4_wx/Darwin.InfoPlist.strings | Bin 456 -> 0 bytes applications/osmo4_wx/Darwin.Osmo.icns | Bin 38570 -> 0 bytes applications/osmo4_wx/Makefile | 94 - applications/osmo4_wx/Playlist.cpp | 826 ------ applications/osmo4_wx/Playlist.h | 134 - applications/osmo4_wx/fileprops.cpp | 608 ----- applications/osmo4_wx/fileprops.h | 83 - applications/osmo4_wx/menubtn.cpp | 863 ------ applications/osmo4_wx/menubtn.h | 314 --- applications/osmo4_wx/osmo4.ico | Bin 15086 -> 0 bytes applications/osmo4_wx/osmo4.xpm | 301 --- applications/osmo4_wx/playlist.xpm | 158 -- applications/osmo4_wx/resource.h | 16 - applications/osmo4_wx/toolbar.xpm | 254 -- applications/osmo4_wx/wxGPACControl.cpp | 1031 -------- applications/osmo4_wx/wxGPACControl.h | 137 - applications/osmo4_wx/wxOsmo4.cpp | 2347 ----------------- applications/osmo4_wx/wxOsmo4.h | 390 --- applications/osmo4_wx/wxOsmo4.rc | 72 - applications/v4studio/V4CommandPanel.cpp | 601 ----- applications/v4studio/V4CommandPanel.h | 103 - applications/v4studio/V4FieldList.cpp | 452 ---- applications/v4studio/V4FieldList.h | 47 - applications/v4studio/V4Node.cpp | 57 - applications/v4studio/V4Node.h | 61 - applications/v4studio/V4NodePool.cpp | 76 - applications/v4studio/V4NodePool.h | 57 - applications/v4studio/V4NodePools.cpp | 121 - applications/v4studio/V4NodePools.h | 59 - applications/v4studio/V4SceneGraph.cpp | 304 --- applications/v4studio/V4SceneGraph.h | 95 - applications/v4studio/V4SceneManager.cpp | 598 ----- applications/v4studio/V4SceneManager.h | 148 -- applications/v4studio/V4Service.cpp | 205 -- applications/v4studio/V4Service.h | 42 - applications/v4studio/V4StudioApp.cpp | 23 - applications/v4studio/V4StudioApp.h | 15 - applications/v4studio/V4StudioFrame.cpp | 951 ------- applications/v4studio/V4StudioFrame.h | 211 -- applications/v4studio/V4StudioTree.cpp | 386 --- applications/v4studio/V4StudioTree.h | 86 - .../v4studio/V4TimeLine/V4TimeLine.cpp | 159 -- applications/v4studio/V4TimeLine/V4TimeLine.h | 84 - .../v4studio/V4TimeLine/V4TimeLineCase.cpp | 186 -- .../v4studio/V4TimeLine/V4TimeLineCase.h | 68 - .../v4studio/V4TimeLine/V4TimeLineElt.cpp | 74 - .../v4studio/V4TimeLine/V4TimeLineElt.h | 48 - .../v4studio/V4TimeLine/V4TimeLineHdr.cpp | 37 - .../v4studio/V4TimeLine/V4TimeLineHdr.h | 36 - .../v4studio/V4TimeLine/V4TimeLineLine.cpp | 92 - .../v4studio/V4TimeLine/V4TimeLineLine.h | 68 - applications/v4studio/install.txt | 110 - applications/v4studio/rc/V4Studio.aps | Bin 60860 -> 0 bytes applications/v4studio/rc/V4Studio.rc | 1 - applications/v4studio/rc/appearance.bmp | Bin 822 -> 0 bytes applications/v4studio/rc/circle.bmp | Bin 1334 -> 0 bytes applications/v4studio/rc/close.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/colortransform.bmp | Bin 310 -> 0 bytes applications/v4studio/rc/copy.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/cut.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/delete.bmp | Bin 774 -> 0 bytes applications/v4studio/rc/fs.bmp | Bin 298 -> 0 bytes applications/v4studio/rc/group.bmp | Bin 310 -> 0 bytes applications/v4studio/rc/ifs2d.bmp | Bin 1334 -> 0 bytes applications/v4studio/rc/ils2d.bmp | Bin 1334 -> 0 bytes applications/v4studio/rc/image.bmp | Bin 822 -> 0 bytes applications/v4studio/rc/layer2d.bmp | Bin 310 -> 0 bytes applications/v4studio/rc/lg.bmp | Bin 774 -> 0 bytes applications/v4studio/rc/lineproperties.bmp | Bin 1378 -> 0 bytes applications/v4studio/rc/material2d.bmp | Bin 1378 -> 0 bytes applications/v4studio/rc/movie.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/new.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/open.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/orderedgroup.bmp | Bin 310 -> 0 bytes applications/v4studio/rc/paste.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/paste_use.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/preview.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/print.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/rect.bmp | Bin 1334 -> 0 bytes applications/v4studio/rc/redo.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/resource_orig.xrc | 75 - applications/v4studio/rc/rg.bmp | Bin 774 -> 0 bytes applications/v4studio/rc/save.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/shape.bmp | Bin 310 -> 0 bytes applications/v4studio/rc/sound.bmp | Bin 774 -> 0 bytes applications/v4studio/rc/t2d.bmp | Bin 310 -> 0 bytes applications/v4studio/rc/text.bmp | Bin 298 -> 0 bytes applications/v4studio/rc/tm2d.bmp | Bin 310 -> 0 bytes applications/v4studio/rc/undo.bmp | Bin 238 -> 0 bytes applications/v4studio/rc/v4.bmp | Bin 1334 -> 0 bytes applications/v4studio/rc/v4.ico | Bin 766 -> 0 bytes applications/v4studio/rc/xlineproperties.bmp | Bin 1378 -> 0 bytes applications/v4studio/safe_include.h | 7 - applications/v4studio/treeIcon1.xpm | 41 - applications/v4studio/treeIcon2.xpm | 42 - applications/v4studio/treeIcon3.xpm | 44 - applications/v4studio/treeIcon4.xpm | 44 - applications/v4studio/treeIcon5.xpm | 43 - applications/v4studio/wxGPACPanel.cpp | 290 -- applications/v4studio/wxGPACPanel.h | 46 - configure | 6 +- 122 files changed, 8 insertions(+), 17087 deletions(-) delete mode 100644 applications/mp4box_android/.classpath delete mode 100644 applications/mp4box_android/.project delete mode 100644 applications/mp4box_android/AndroidManifest.xml delete mode 100644 applications/mp4box_android/default.properties delete mode 100644 applications/mp4box_android/gen/org/enst/mp4box/R.java delete mode 100644 applications/mp4box_android/proguard.cfg delete mode 100644 applications/mp4box_android/res/drawable-hdpi/icon.png delete mode 100644 applications/mp4box_android/res/drawable-ldpi/icon.png delete mode 100644 applications/mp4box_android/res/drawable-mdpi/icon.png delete mode 100644 applications/mp4box_android/res/layout/main.xml delete mode 100644 applications/mp4box_android/res/values/strings.xml delete mode 100644 applications/mp4box_android/src/com/enst/mp4box/mp4box.java delete mode 100644 applications/mp4box_android/src/com/enst/mp4box/mp4terminal.java delete mode 100644 applications/osmo4_ios/Resources/icon.png delete mode 100644 applications/osmo4_ios/Resources/osmo.icns delete mode 100644 applications/osmo4_ios/extract.c delete mode 100644 applications/osmo4_ios/main.c delete mode 100644 applications/osmo4_ios/osmo4ios-Info.plist delete mode 100644 applications/osmo4_wx/Darwin.Info.plist delete mode 100644 applications/osmo4_wx/Darwin.InfoPlist.strings delete mode 100644 applications/osmo4_wx/Darwin.Osmo.icns delete mode 100644 applications/osmo4_wx/Makefile delete mode 100644 applications/osmo4_wx/Playlist.cpp delete mode 100644 applications/osmo4_wx/Playlist.h delete mode 100644 applications/osmo4_wx/fileprops.cpp delete mode 100644 applications/osmo4_wx/fileprops.h delete mode 100644 applications/osmo4_wx/menubtn.cpp delete mode 100644 applications/osmo4_wx/menubtn.h delete mode 100644 applications/osmo4_wx/osmo4.ico delete mode 100644 applications/osmo4_wx/osmo4.xpm delete mode 100644 applications/osmo4_wx/playlist.xpm delete mode 100644 applications/osmo4_wx/resource.h delete mode 100644 applications/osmo4_wx/toolbar.xpm delete mode 100644 applications/osmo4_wx/wxGPACControl.cpp delete mode 100644 applications/osmo4_wx/wxGPACControl.h delete mode 100644 applications/osmo4_wx/wxOsmo4.cpp delete mode 100644 applications/osmo4_wx/wxOsmo4.h delete mode 100644 applications/osmo4_wx/wxOsmo4.rc delete mode 100644 applications/v4studio/V4CommandPanel.cpp delete mode 100644 applications/v4studio/V4CommandPanel.h delete mode 100644 applications/v4studio/V4FieldList.cpp delete mode 100644 applications/v4studio/V4FieldList.h delete mode 100644 applications/v4studio/V4Node.cpp delete mode 100644 applications/v4studio/V4Node.h delete mode 100644 applications/v4studio/V4NodePool.cpp delete mode 100644 applications/v4studio/V4NodePool.h delete mode 100644 applications/v4studio/V4NodePools.cpp delete mode 100644 applications/v4studio/V4NodePools.h delete mode 100644 applications/v4studio/V4SceneGraph.cpp delete mode 100644 applications/v4studio/V4SceneGraph.h delete mode 100644 applications/v4studio/V4SceneManager.cpp delete mode 100644 applications/v4studio/V4SceneManager.h delete mode 100644 applications/v4studio/V4Service.cpp delete mode 100644 applications/v4studio/V4Service.h delete mode 100644 applications/v4studio/V4StudioApp.cpp delete mode 100644 applications/v4studio/V4StudioApp.h delete mode 100644 applications/v4studio/V4StudioFrame.cpp delete mode 100644 applications/v4studio/V4StudioFrame.h delete mode 100644 applications/v4studio/V4StudioTree.cpp delete mode 100644 applications/v4studio/V4StudioTree.h delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLine.cpp delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLine.h delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLineCase.cpp delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLineCase.h delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLineElt.cpp delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLineElt.h delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLineHdr.cpp delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLineHdr.h delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLineLine.cpp delete mode 100644 applications/v4studio/V4TimeLine/V4TimeLineLine.h delete mode 100644 applications/v4studio/install.txt delete mode 100644 applications/v4studio/rc/V4Studio.aps delete mode 100644 applications/v4studio/rc/V4Studio.rc delete mode 100644 applications/v4studio/rc/appearance.bmp delete mode 100644 applications/v4studio/rc/circle.bmp delete mode 100644 applications/v4studio/rc/close.bmp delete mode 100644 applications/v4studio/rc/colortransform.bmp delete mode 100644 applications/v4studio/rc/copy.bmp delete mode 100644 applications/v4studio/rc/cut.bmp delete mode 100644 applications/v4studio/rc/delete.bmp delete mode 100644 applications/v4studio/rc/fs.bmp delete mode 100644 applications/v4studio/rc/group.bmp delete mode 100644 applications/v4studio/rc/ifs2d.bmp delete mode 100644 applications/v4studio/rc/ils2d.bmp delete mode 100644 applications/v4studio/rc/image.bmp delete mode 100644 applications/v4studio/rc/layer2d.bmp delete mode 100644 applications/v4studio/rc/lg.bmp delete mode 100644 applications/v4studio/rc/lineproperties.bmp delete mode 100644 applications/v4studio/rc/material2d.bmp delete mode 100644 applications/v4studio/rc/movie.bmp delete mode 100644 applications/v4studio/rc/new.bmp delete mode 100644 applications/v4studio/rc/open.bmp delete mode 100644 applications/v4studio/rc/orderedgroup.bmp delete mode 100644 applications/v4studio/rc/paste.bmp delete mode 100644 applications/v4studio/rc/paste_use.bmp delete mode 100644 applications/v4studio/rc/preview.bmp delete mode 100644 applications/v4studio/rc/print.bmp delete mode 100644 applications/v4studio/rc/rect.bmp delete mode 100644 applications/v4studio/rc/redo.bmp delete mode 100644 applications/v4studio/rc/resource_orig.xrc delete mode 100644 applications/v4studio/rc/rg.bmp delete mode 100644 applications/v4studio/rc/save.bmp delete mode 100644 applications/v4studio/rc/shape.bmp delete mode 100644 applications/v4studio/rc/sound.bmp delete mode 100644 applications/v4studio/rc/t2d.bmp delete mode 100644 applications/v4studio/rc/text.bmp delete mode 100644 applications/v4studio/rc/tm2d.bmp delete mode 100644 applications/v4studio/rc/undo.bmp delete mode 100644 applications/v4studio/rc/v4.bmp delete mode 100644 applications/v4studio/rc/v4.ico delete mode 100644 applications/v4studio/rc/xlineproperties.bmp delete mode 100644 applications/v4studio/safe_include.h delete mode 100644 applications/v4studio/treeIcon1.xpm delete mode 100644 applications/v4studio/treeIcon2.xpm delete mode 100644 applications/v4studio/treeIcon3.xpm delete mode 100644 applications/v4studio/treeIcon4.xpm delete mode 100644 applications/v4studio/treeIcon5.xpm delete mode 100644 applications/v4studio/wxGPACPanel.cpp delete mode 100644 applications/v4studio/wxGPACPanel.h diff --git a/Makefile b/Makefile index 1d56214..d7635e5 100644 --- a/Makefile +++ b/Makefile @@ -55,9 +55,13 @@ tar: install: $(INSTALL) -d "$(DESTDIR)$(prefix)" + $(INSTALL) -d "$(DESTDIR)$(prefix)/$(libdir)" $(INSTALL) -d "$(DESTDIR)$(prefix)/bin" $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Box "$(DESTDIR)$(prefix)/bin" $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Client "$(DESTDIR)$(prefix)/bin" + if [ -d $(DESTDIR)$(prefix)/$(libdir)/pkgconfig ] ; then \ + $(INSTALL) $(INSTFLAGS) -m 644 gpac.pc "$(DESTDIR)$(prefix)/$(libdir)/pkgconfig" ; \ + fi $(INSTALL) -d "$(DESTDIR)$(moddir)" $(INSTALL) bin/gcc/*.$(DYN_LIB_SUFFIX) "$(DESTDIR)$(moddir)" rm -f $(DESTDIR)$(moddir)/libgpac.$(DYN_LIB_SUFFIX) @@ -88,6 +92,7 @@ uninstall: $(MAKE) -C applications uninstall rm -rf $(DESTDIR)$(moddir) rm -rf $(DESTDIR)$(prefix)/$(libdir)/libgpac* + rm -rf $(DESTDIR)$(prefix)/$(libdir)/pkgconfig/gpac.pc rm -rf $(DESTDIR)$(prefix)/bin/MP4Box rm -rf $(DESTDIR)$(prefix)/bin/MP4Client rm -rf $(DESTDIR)$(mandir)/man1/mp4box.1 diff --git a/applications/mp4box/main.c b/applications/mp4box/main.c index 332aaaf..a516aa9 100644 --- a/applications/mp4box/main.c +++ b/applications/mp4box/main.c @@ -1948,7 +1948,7 @@ int mp4boxMain(int argc, char **argv) else if (!stricmp(arg, "-split-chunk") || !stricmp(arg, "-splitx") || !stricmp(arg, "-splitz")) { CHECK_NEXT_ARG if (!strstr(argv[i+1], ":")) { - fprintf(stdout, "Chunk extraction usage: \"-splitx start->end\" expressed in seconds\n"); + fprintf(stdout, "Chunk extraction usage: \"-splitx start:end\" expressed in seconds\n"); return 1; } sscanf(argv[i+1], "%lf:%lf", &split_start, &split_duration); diff --git a/applications/mp4box_android/.classpath b/applications/mp4box_android/.classpath deleted file mode 100644 index 609aa00..0000000 --- a/applications/mp4box_android/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/applications/mp4box_android/.project b/applications/mp4box_android/.project deleted file mode 100644 index d7f5daa..0000000 --- a/applications/mp4box_android/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - mp4box - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/applications/mp4box_android/AndroidManifest.xml b/applications/mp4box_android/AndroidManifest.xml deleted file mode 100644 index ba98ed9..0000000 --- a/applications/mp4box_android/AndroidManifest.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - diff --git a/applications/mp4box_android/default.properties b/applications/mp4box_android/default.properties deleted file mode 100644 index e2e8061..0000000 --- a/applications/mp4box_android/default.properties +++ /dev/null @@ -1,11 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "build.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-8 diff --git a/applications/mp4box_android/gen/org/enst/mp4box/R.java b/applications/mp4box_android/gen/org/enst/mp4box/R.java deleted file mode 100644 index 399c89c..0000000 --- a/applications/mp4box_android/gen/org/enst/mp4box/R.java +++ /dev/null @@ -1,30 +0,0 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package com.enst.mp4box; - -public final class R { - public static final class attr { - } - public static final class drawable { - public static final int icon=0x7f020000; - } - public static final class id { - public static final int CommandLineEdit=0x7f050001; - public static final int OkButton=0x7f050002; - public static final int textView1=0x7f050000; - } - public static final class layout { - public static final int main=0x7f030000; - } - public static final class string { - public static final int CommandLineTitle=0x7f040002; - public static final int OkButton=0x7f040003; - public static final int app_name=0x7f040001; - public static final int hello=0x7f040000; - } -} diff --git a/applications/mp4box_android/proguard.cfg b/applications/mp4box_android/proguard.cfg deleted file mode 100644 index 12dd039..0000000 --- a/applications/mp4box_android/proguard.cfg +++ /dev/null @@ -1,36 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class * extends android.app.backup.BackupAgentHelper --keep public class * extends android.preference.Preference --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native ; -} - --keepclasseswithmembernames class * { - public (android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembernames class * { - public (android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/applications/mp4box_android/res/drawable-hdpi/icon.png b/applications/mp4box_android/res/drawable-hdpi/icon.png deleted file mode 100644 index 8074c4c571b8cd19e27f4ee5545df367420686d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4147 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 diff --git a/applications/mp4box_android/res/drawable-ldpi/icon.png b/applications/mp4box_android/res/drawable-ldpi/icon.png deleted file mode 100644 index 1095584ec21f71cd0afc9e0993aa2209671b590c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1723 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 - - - - - diff --git a/applications/mp4box_android/res/values/strings.xml b/applications/mp4box_android/res/values/strings.xml deleted file mode 100644 index dece8e7..0000000 --- a/applications/mp4box_android/res/values/strings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Hello World, mp4box! - mp4box - Command Line : - Ok - diff --git a/applications/mp4box_android/src/com/enst/mp4box/mp4box.java b/applications/mp4box_android/src/com/enst/mp4box/mp4box.java deleted file mode 100644 index 4a3f1e7..0000000 --- a/applications/mp4box_android/src/com/enst/mp4box/mp4box.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.enst.mp4box; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import com.enst.mp4box.R; - -import android.app.Activity; -import android.os.Bundle; -import android.widget.Button; -import android.widget.EditText; -import android.util.Log; -import android.view.View; - - - -public class mp4box extends Activity { - private mp4terminal myTerminal; - - /** Called when the activity is first created. */ - @Override - - - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - myTerminal = new mp4terminal(); - errors = loadAllLibraries(); - System.out.println( "hello world java" ); - final Button button = (Button) findViewById(R.id.OkButton); - - button.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - EditText oCommandLine = (EditText) findViewById(R.id.CommandLineEdit ); - CharSequence sCommandLine = oCommandLine.getText(); - myTerminal.run( sCommandLine.toString() ); - //showKeyboard( true ); - } - }); - - } - - - - - private static Map errors = null; - - synchronized static Map loadAllLibraries() - { - if( errors != null) - return errors; - StringBuilder sb = new StringBuilder(); - final String[] toLoad = { "GLESv1_CM", "dl", "log",//$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ - "jpeg", "javaenv", //$NON-NLS-1$ //$NON-NLS-2$ - "mad", "editline", "ft2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - "js_osmo", "openjpeg", "png", "z", //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ - "ffmpeg", "faad", "gpac", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - "stdc++", "mp4box" }; // //$NON-NLS-1$ //$NON-NLS-2$ - HashMap exceptions = new HashMap(); - for (String s : toLoad) { - try { - String msg = "Loading library " + s + "...";//$NON-NLS-1$//$NON-NLS-2$ - sb.append(msg); - //Log.i(LOG_LIB, msg); - System.loadLibrary(s); - } catch (UnsatisfiedLinkError e) { - sb.append("Failed to load " + s + ", error=" + e.getLocalizedMessage() + " :: " //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - + e.getClass().getSimpleName() + "\n"); //$NON-NLS-1$ - exceptions.put(s, e); - //Log.e(LOG_LIB, "Failed to load library : " + s + " due to link error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (SecurityException e) { - exceptions.put(s, e); - //Log.e(LOG_LIB, "Failed to load library : " + s + " due to security error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (Throwable e) { - exceptions.put(s, e); - //Log.e(LOG_LIB, "Failed to load library : " + s + " due to Runtime error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /*if (!exceptions.isEmpty()) { - try { - PrintStream out = new PrintStream(config.getGpacConfigDirectory() + "debug_libs.txt", "UTF-8"); //$NON-NLS-1$//$NON-NLS-2$ - out.println("$Revision: 2972 $"); //$NON-NLS-1$ - out.println(new Date()); - out.println("\n*** Configuration\n"); //$NON-NLS-1$ - out.println(config.getConfigAsText()); - sb.append("*** Libs listing: "); //$NON-NLS-1$ - sb.append(config.getGpacLibsDirectory()); - sb.append('\n'); - listing(sb, new File(config.getGpacLibsDirectory()), 2); - sb.append("*** Modules listing: "); //$NON-NLS-1$ - sb.append(config.getGpacModulesDirectory()); - sb.append('\n'); - listing(sb, new File(config.getGpacModulesDirectory()), 2); - sb.append("*** Fonts listing: \n"); //$NON-NLS-1$ - sb.append(config.getGpacFontDirectory()); - sb.append('\n'); - listing(sb, new File(config.getGpacFontDirectory()), 2); - sb.append("*** Exceptions:\n"); //$NON-NLS-1$ - for (Map.Entry ex : exceptions.entrySet()) { - sb.append(ex.getKey()).append(": ") //$NON-NLS-1$ - .append(ex.getValue().getLocalizedMessage()) - .append('(') - .append(ex.getValue().getClass()) - .append(")\n"); //$NON-NLS-1$ - } - out.println(sb.toString()); - out.flush(); - out.close(); - } catch (Exception e) { - Log.e(LOG_LIB, "Failed to output debug info to debug file", e); //$NON-NLS-1$ - } - }*/ - errors = Collections.unmodifiableMap(exceptions); - return errors; -} - /*public void showKeyboard(boolean showKeyboard) { - if (keyboardIsVisible == showKeyboard == true) - return; - InputMethodManager mgr = ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)); - this.keyboardIsVisible = showKeyboard; - if (showKeyboard) - mgr.showSoftInput(findViewById(R.id.CommandLineEdit ), 0); - else - mgr.hideSoftInputFromInputMethod(findViewById(R.id.CommandLineEdit ).getWindowToken(), 0); - - }*/ -} \ No newline at end of file diff --git a/applications/mp4box_android/src/com/enst/mp4box/mp4terminal.java b/applications/mp4box_android/src/com/enst/mp4box/mp4terminal.java deleted file mode 100644 index 7b77bb6..0000000 --- a/applications/mp4box_android/src/com/enst/mp4box/mp4terminal.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.enst.mp4box; - - -public class mp4terminal { - - public native void run( String sCommandLine); -} diff --git a/applications/osmo4_ios/Resources/icon.png b/applications/osmo4_ios/Resources/icon.png deleted file mode 100644 index 13f1dee1cbed855335c048d2321c4f60a5598f0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7682 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 diff --git a/applications/osmo4_ios/Resources/osmo.icns b/applications/osmo4_ios/Resources/osmo.icns deleted file mode 100644 index da7226f64f8939dfd5fddf847699e6f2ba13250b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147235 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 diff --git a/applications/osmo4_ios/extract.c b/applications/osmo4_ios/extract.c deleted file mode 100644 index 8d100c8..0000000 --- a/applications/osmo4_ios/extract.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * Copyright (c) 2005-200X ENST - * All rights reserved - * - * This file is part of GPAC / command-line client - * - * GPAC is gf_free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "libgpac_symbols.h" - -#ifdef WIN32 -#include -#else -typedef struct tagBITMAPFILEHEADER -{ - u16 bfType; - u32 bfSize; - u16 bfReserved1; - u16 bfReserved2; - u32 bfOffBits; -} BITMAPFILEHEADER; - -typedef struct tagBITMAPINFOHEADER{ - u32 biSize; - s32 biWidth; - s32 biHeight; - u16 biPlanes; - u16 biBitCount; - u32 biCompression; - u32 biSizeImage; - s32 biXPelsPerMeter; - s32 biYPelsPerMeter; - u32 biClrUsed; - u32 biClrImportant; -} BITMAPINFOHEADER; - -#define BI_RGB 0L - -#endif - - -#include -#include -#include - -extern Bool is_connected; -extern GF_Terminal *term; -extern u32 Duration; -extern GF_Err last_error; - -static GFINLINE u8 colmask(s32 a, s32 n) -{ - s32 mask = (1 << n) - 1; - return (u8) (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask); -} - -static u32 put_pixel(FILE *fout, u32 type, u32 pf, char *ptr) -{ - u16 col; - switch (pf) { - case GF_PIXEL_RGB_32: - case GF_PIXEL_ARGB: - fputc(ptr[0], fout); - fputc(ptr[1], fout); - fputc(ptr[2], fout); - return 4; - - case GF_PIXEL_BGR_32: - case GF_PIXEL_RGBA: - //probably due to tinygl bug - verify -#ifndef GPAC_USE_TINYGL - fputc(ptr[3], fout); - fputc(ptr[2], fout); - fputc(ptr[1], fout); -#else - fputc(ptr[2], fout); - fputc(ptr[1], fout); - fputc(ptr[0], fout); -#endif - return 4; - - case GF_PIXEL_RGB_24: - fputc(ptr[2], fout); - fputc(ptr[1], fout); - fputc(ptr[0], fout); - return 3; - - case GF_PIXEL_BGR_24: - fputc(ptr[2], fout); - fputc(ptr[1], fout); - fputc(ptr[0], fout); - return 3; - case GF_PIXEL_RGB_565: - col = * (u16 *)ptr; - fputc(colmask(col << 3, 3), fout); - fputc(colmask(col >> (5 - 2), 2), fout); - fputc(colmask(col >> (11 - 3), 3), fout); - return 2; - - case GF_PIXEL_RGB_555: - col = * (u16 *)ptr; - fputc(colmask(col << 3, 3), fout); - fputc(colmask(col >> (5 - 3), 3), fout); - fputc(colmask(col >> (10 - 3), 3), fout); - return 2; - /* this is used to write the byte depthbuffer in greyscale when dumping depth*/ - case GF_PIXEL_GREYSCALE: - /* bmp always needs 3 pixels */ - fputc(ptr[0], fout); - fputc(ptr[0], fout); - fputc(ptr[0], fout); - /* if printing the characters corresponding to the float depth buffer: */ - /* - { - u32 i=0; - while (ptr[i]!='\0') { - fputc(ptr[i], fout); - i++; - } - fputc('\b', fout); - } - */ - return 1; - - - case 0: - fputc(ptr[0], fout); - return 1; - } - return 0; -} - -void write_bmp(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ - char str[GF_MAX_PATH]; - BITMAPFILEHEADER fh; - BITMAPINFOHEADER fi; - FILE *fout; - u32 j, i; - char *ptr, *prev; - - prev = strrchr(rad_name, '.'); - //if (prev) prev[0] = '\0'; - - if (fb->pixel_format==GF_PIXEL_GREYSCALE) sprintf(str, "%s_%d_depth.bmp", rad_name, img_num); - else sprintf(str, "%s_%d.bmp", rad_name, img_num); - - fout = gf_f64_open(str, "wb"); - if (!fout) return; - - memset(&fh, 0, sizeof(fh)); - fh.bfType = 19778; - fh.bfOffBits = 14 + 40; - - memset(&fi, 0, sizeof(char)*40); - fi.biSize = sizeof(char)*40; - fi.biWidth = fb->width; - fi.biHeight = fb->height; - fi.biPlanes = 1; - if (fb->pixel_format==GF_PIXEL_GREYSCALE) fi.biBitCount = 24; - else fi.biBitCount = 24; - fi.biCompression = BI_RGB; - fi.biSizeImage = fb->pitch_y * fb->height; - - /*NOT ALIGNED!!*/ - gf_fwrite(&fh.bfType, 2, 1, fout); - gf_fwrite(&fh.bfSize, 4, 1, fout); - gf_fwrite(&fh.bfReserved1, 2, 1, fout); - gf_fwrite(&fh.bfReserved2, 2, 1, fout); - gf_fwrite(&fh.bfOffBits, 4, 1, fout); - - gf_fwrite(&fi, 1, 40, fout); -//#ifndef GPAC_USE_TINYGL - for (j=fb->height; j>0; j--) { - ptr = fb->video_buffer + (j-1)*fb->pitch_y; - for (i=0;iwidth; i++) { - u32 res = put_pixel(fout, 0, fb->pixel_format, ptr); - assert(res); - ptr += res; - } - } -//#else -#if 0 - for (j=0; jheight; j++) { - ptr = fb->video_buffer + j*fb->pitch; - for (i=0;iwidth; i++) { - u32 res = put_pixel(fout, 0, fb->pixel_format, ptr); - assert(res); - ptr += res; - } - } -#endif - - fclose(fout); -} - -/*writes onto a file the content of the framebuffer in *fb interpreted as the byte depthbuffer */ -/*it's also possible to write a float depthbuffer by passing the floats to strings and writing chars in putpixel - see comments*/ -void write_depthfile(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ - FILE *fout; - u32 i, j; - char val; - unsigned char *depth; - - depth = (unsigned char *) fb->video_buffer; - - fout = gf_f64_open("dump_depth", "wb"); - if (!fout) return; - for (j=0; jheight; j++) { - for (i=0;iwidth; i++) { - -#ifdef GPAC_USE_TINYGL - val = fputc(depth[2*i+j*fb->width*sizeof(unsigned short)], fout); - val = fputc(depth[2*i+j*fb->width*sizeof(unsigned short) + 1], fout); -#else - val = fputc(depth[i+j*fb->width], fout); -#endif - } - } - fclose(fout); -} - -void write_texture_file(GF_VideoSurface *fb, char *rad_name, u32 img_num, u32 dump_mode) -{ - - FILE *fout; - u32 i, j; - char val; - unsigned char *buf; - - buf = (unsigned char *) fb->video_buffer; - - if (dump_mode==6) fout = gf_f64_open("dump_rgbds", "wb"); - else if (dump_mode==9) fout = gf_f64_open("dump_rgbd", "wb"); - else return; - - if (!fout) return; - for (j=0; jheight; j++) { - for (i=0;iwidth*4; i++) { - val = fputc(buf[i+j*fb->pitch_y], fout); - } - } - fclose(fout); -} - - -void write_raw(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ - u32 j, i; - char *ptr, *prev; - char str[GF_MAX_PATH]; - FILE *fout; - prev = strrchr(rad_name, '.'); - if (prev) prev[0] = '\0'; - if (img_num<10) { - sprintf(str, "%s_00%d.raw", rad_name, img_num); - } else if (img_num<100) { - sprintf(str, "%s_0%d.raw", rad_name, img_num); - } else { - sprintf(str, "%s_%d.raw", rad_name, img_num); - } - - fout = gf_f64_open(str, "wb"); - if (!fout) return; - - - for (j=0;jheight; j++) { - ptr = fb->video_buffer + j*fb->pitch_y; - for (i=0;iwidth; i++) { - u32 res = put_pixel(fout, 0, fb->pixel_format, ptr); - assert(res); - ptr += res; - } - } - fclose(fout); -} - - -/* creates a .bmp format greyscale image of the byte depthbuffer and a binary with only the content of the depthbuffer */ -void dump_depth (GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, char *conv_buf, void *avi_out) -{ - GF_Err e; - u32 i, k; - GF_VideoSurface fb; - - /*lock it*/ - e = gf_sc_get_screen_buffer(term->compositor, &fb, 1); - if (e) fprintf(stdout, "Error grabbing depth buffer: %s\n", gf_error_to_string(e)); - else fprintf(stdout, "OK\n"); - /*export frame*/ - switch (dump_type) { - case 1: - case 8: - /*reverse frame*/ - for (k=0; k> 8/*(11 - 3)*/, 3); - dst[1] = colmask(src_16 >> 3/*(5 - 2)*/, 2); - dst[0] = colmask(src_16 << 3, 3); - src+=2; - break; - case GF_PIXEL_RGB_555: - src_16 = * (u16 *)src; - dst[2] = colmask(src_16 >> 7/*(10 - 3)*/, 3); - dst[1] = colmask(src_16 >> 2/*(5 - 3)*/, 3); - dst[0] = colmask(src_16 << 3, 3); - src+=2; - break; - /*for depth .avi*/ - case GF_PIXEL_GREYSCALE: - dst[0] = src[0]; - dst[1] = src[0]; - dst[2] = src[0]; - src+=1; - break; - } - dst += 3; - } - } -#ifndef GPAC_DISABLE_AVILIB - if (AVI_write_frame(avi_out, conv_buf, fb.height*fb.width*3, 1) <0) - printf("Error writing frame\n"); -#endif - break; - case 2: - write_bmp(&fb, rad_name, frameNum); - break; - case 3: - write_raw(&fb, rad_name, frameNum); - break; - case 4: - write_depthfile(&fb, rad_name, frameNum); - break; - case 7: - write_bmp(&fb, rad_name, frameNum); - break; - - } - /*unlock it*/ - /*in -depth -avi mode, do not release it yet*/ - if (dump_type!=8) gf_sc_release_screen_buffer(term->compositor, &fb); -} - -void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, char *conv_buf, void *avi_out) -{ - GF_Err e = GF_OK; - u32 i, k, out_size; - GF_VideoSurface fb; - - /*lock it*/ - if (dump_type==5 || dump_type==6) e = gf_sc_get_screen_buffer(term->compositor, &fb, 2); - else if (dump_type== 9 || dump_type==10) e = gf_sc_get_screen_buffer(term->compositor, &fb, 3); - else e = gf_sc_get_screen_buffer(term->compositor, &fb, 0); - if (e) fprintf(stdout, "Error grabbing frame buffer: %s\n", gf_error_to_string(e)); - - if (dump_type!=5 && dump_type!= 10) { - out_size = fb.height*fb.width*3; - } else { - out_size = fb.height*fb.width*4; - } - /*export frame*/ - switch (dump_type) { - case 1: - case 5: - case 10: - case 8: - /*reverse frame*/ - for (k=0; k> 8/*(11 - 3)*/, 3); - dst[1] = colmask(src_16 >> 3/*(5 - 2)*/, 2); - dst[0] = colmask(src_16 << 3, 3); - src+=2; - dst+=3; - } - break; - case GF_PIXEL_RGB_555: - for (i=0;i> 7/*(10 - 3)*/, 3); - dst[1] = colmask(src_16 >> 2/*(5 - 3)*/, 3); - dst[0] = colmask(src_16 << 3, 3); - src+=2; - dst +=3; - } - break; - } - } -#ifndef GPAC_DISABLE_AVILIB - if (dump_type!=5 && dump_type!= 10) { - if (AVI_write_frame(avi_out, conv_buf, out_size, 1) <0) - printf("Error writing frame\n"); - } else { - if (AVI_write_frame(avi_out, conv_buf, out_size, 1) <0) - printf("Error writing frame\n"); - } -#endif - break; - case 2: - write_bmp(&fb, rad_name, frameNum); - break; - case 6: - case 9: - write_texture_file(&fb, rad_name, frameNum, dump_type); - break; - - case 3: - write_raw(&fb, rad_name, frameNum); - break; - } - /*unlock it*/ - gf_sc_release_screen_buffer(term->compositor, &fb); -} - -Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Float scale, u32 *times, u32 nb_times) -{ - GF_Err e; - u32 i = 0; - GF_VideoSurface fb; - char szPath[GF_MAX_PATH]; - char *prev=NULL; - - prev = strstr(url, "://"); - if (prev) { - prev = strrchr(url, '/'); - if (prev) prev++; - } - - if (!prev) prev = url; - strcpy(szPath, prev); - prev = strrchr(szPath, '.'); - if (prev) prev[0] = 0; - - fprintf(stdout, "Opening URL %s\n", url); - /*connect in pause mode*/ - gf_term_connect_from_time(term, url, 0, 1); - - while (!term->compositor->scene - || term->compositor->msg_type - || (gf_term_get_option(term, GF_OPT_PLAY_STATE) == GF_STATE_STEP_PAUSE) - ) { - if (last_error) return 1; - gf_term_process_flush(term); - gf_sleep(10); - } - - if (width && height) { - gf_term_set_size(term, width, height); - gf_term_process_flush(term); - } -#ifndef GPAC_USE_TINYGL - printf("not tinygl\n"); - e = gf_sc_get_screen_buffer(term->compositor, &fb, 0); -#else - printf("tinygl\n"); - e = gf_sc_get_screen_buffer(term->compositor, &fb, 1); -#endif - if (e != GF_OK) { - fprintf(stdout, "Error grabbing screen buffer: %s\n", gf_error_to_string(e)); - return 0; - } - width = fb.width; - height = fb.height; - gf_sc_release_screen_buffer(term->compositor, &fb); - - if (scale != 1) { - width = (u32)(width * scale); - height = (u32)(height * scale); - gf_term_set_size(term, width, height); - gf_term_process_flush(term); - } - - /*we work in RGB24, and we must make sure the pitch is %4*/ - if ((width*3)%4) { - fprintf(stdout, "Adjusting width (%d) to have a stride multiple of 4\n", width); - while ((width*3)%4) width--; - - gf_term_set_size(term, width, height); - gf_term_process_flush(term); - - gf_sc_get_screen_buffer(term->compositor, &fb, 0); - width = fb.width; - height = fb.height; - gf_sc_release_screen_buffer(term->compositor, &fb); - } - - if (dump_mode==1 || dump_mode==5 || dump_mode==8 || dump_mode==10) { -#ifdef GPAC_DISABLE_AVILIB - fprintf(stdout, "AVILib is disabled in this build of GPAC\n"); - return 0; -#else - u32 time, prev_time, nb_frames, dump_dur; - char *conv_buf; - avi_t *avi_out = NULL; - avi_t *depth_avi_out = NULL; - char szPath_depth[GF_MAX_PATH]; - char comp[5]; - strcpy(szPath_depth, szPath); - strcat(szPath, ".avi"); - avi_out = AVI_open_output_file(szPath); - if (!avi_out) { - fprintf(stdout, "Error creating AVI file %s\n", szPath); - return 1; - } - if (dump_mode==8) { - strcat(szPath_depth, "_depth.avi"); - depth_avi_out = AVI_open_output_file(szPath_depth); - if (!depth_avi_out) { - fprintf(stdout, "Error creating AVI file %s\n", szPath); - return 1; - } - } - - if (!fps) fps = 25.0; - time = prev_time = 0; - nb_frames = 0; - - if (nb_times==2) { - prev_time = times[0]; - dump_dur = times[1] - times[0]; - } else { - dump_dur = times[0] ? times[0] : Duration; - } - if (!dump_dur) { - fprintf(stdout, "Warning: file has no duration, defaulting to 1 sec\n"); - dump_dur = 1000; - } - - comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0; - AVI_set_video(avi_out, width, height, fps, comp); - if (dump_mode==8) AVI_set_video(depth_avi_out, width, height, fps, comp); - if (dump_mode != 5 && dump_mode!=10) conv_buf = gf_malloc(sizeof(char) * width * height * 3); - else conv_buf = gf_malloc(sizeof(char) * width * height * 4); - /*step to first frame*/ - if (prev_time) gf_term_step_clocks(term, prev_time); - - while (time < dump_dur) { - while ((gf_term_get_option(term, GF_OPT_PLAY_STATE) == GF_STATE_STEP_PAUSE)) { - gf_term_process_flush(term); - } - fprintf(stdout, "Dumping %02d/100\r", (u32) ((100.0*prev_time)/dump_dur) ); - - if (dump_mode==8) { - /*we'll dump both buffers at once*/ - gf_mx_p(term->compositor->mx); - dump_depth(term, szPath_depth, dump_mode, i+1, conv_buf, depth_avi_out); - dump_frame(term, szPath, dump_mode, i+1, conv_buf, avi_out); - gf_mx_v(term->compositor->mx); - - } - else dump_frame(term, szPath, dump_mode, i+1, conv_buf, avi_out); - - nb_frames++; - time = (u32) (nb_frames*1000/fps); - gf_term_step_clocks(term, time - prev_time); - prev_time = time; - } - AVI_close(avi_out); - if (dump_mode==8) AVI_close(depth_avi_out); - gf_free(conv_buf); - fprintf(stdout, "AVI Extraction 100/100\n"); -#endif /*GPAC_DISABLE_AVILIB*/ - } else { - if (times[0]) gf_term_step_clocks(term, times[0]); - - for (i=0; i -#include - -#else -#include /*for GetModuleFileName*/ -#include /*for _mkdir*/ -#include /*for getting user-dir*/ -#ifndef SHGFP_TYPE_CURRENT -#define SHGFP_TYPE_CURRENT 0 /*needed for MinGW*/ -#endif - -#ifdef _MSC_VER -/*get rid of console*/ -#if 0 -#pragma comment(linker,"/SUBSYSTEM:WINDOWS") -#pragma comment(linker,"/ENTRY:main") -#else -#pragma comment(linker,"/SUBSYSTEM:CONSOLE") -#endif - -#endif // _MSC_VER - -#endif //WIN32 - - -/*local prototypes*/ -void PrintWorldInfo(GF_Terminal *term); -void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number); -void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name); - -void ViewODs(GF_Terminal *term, Bool show_timing); -void PrintGPACConfig(); - -static Bool restart = 0; -#if defined(__DARWIN__) || defined(__APPLE__) -static Bool not_threaded = 1; -#else -static Bool not_threaded = 0; -#endif -static Bool no_audio = 0; -static Bool no_regulation = 0; -static Bool bench_mode = 0; -Bool is_connected = 0; -Bool startup_file = 0; -GF_User user; -GF_Terminal *term; -u64 Duration; -GF_Err last_error = GF_OK; - -static Fixed bench_speed = FLT2FIX(20); - -static Bool request_next_playlist_item = 0; - -static GF_Config *cfg_file; -static Bool display_rti = 0; -static Bool Run; -static Bool CanSeek = 0; -static u32 Volume=100; -static char the_url[GF_MAX_PATH]; -static char pl_path[GF_MAX_PATH]; -static Bool no_mime_check = 1; -static Bool be_quiet = 0; -static u32 log_time_start = 0; - -static u32 forced_width=0; -static u32 forced_height=0; - -/*windowless options*/ -u32 align_mode = 0; -u32 init_w = 0; -u32 init_h = 0; -u32 last_x, last_y; -Bool right_down = 0; - -void dump_frame(GF_Terminal *term, char *rad_path, u32 dump_type, u32 frameNum); -Bool dump_file(char *the_url, u32 dump_mode, Double fps, u32 width, u32 height, Float scale, u32 *times, u32 nb_times); - -void PrintUsage() -{ - fprintf(stdout, "Usage Osmo4iOS [options] [filename]\n" - "\t-c fileName: user-defined configuration file\n" - "\t-rti fileName: logs run-time info (FPS, CPU, Mem usage) to file\n" - "\t-rtix fileName: same as -rti but driven by GPAC logs\n" - "\t-quiet: removes script message, buffering and downloading status\n" - "\t-opt option: Overrides an option in the configuration file. String format is section:key=value\n" - "\t-log-file file: sets output log file.\n" - "\t-log-level lev: sets log level. Possible values are:\n" - "\t \"error\" : logs only error messages\n" - "\t \"warning\" : logs error+warning messages\n" - "\t \"info\" : logs error+warning+info messages\n" - "\t \"debug\" : logs all messages\n" - "\n" - "\t-log-tools lt: sets tool(s) to log. List of \':\'-separated values:\n" - "\t \"core\" : libgpac core\n" - "\t \"coding\" : bitstream formats (audio, video, scene)\n" - "\t \"container\" : container formats (ISO File, MPEG-2 TS, AVI, ...)\n" - "\t \"network\" : network data exept RTP trafic\n" - "\t \"rtp\" : rtp trafic\n" - "\t \"author\" : authoring tools (hint, import, export)\n" - "\t \"sync\" : terminal sync layer\n" - "\t \"codec\" : terminal codec messages\n" - "\t \"parser\" : scene parsers (svg, xmt, bt) and other\n" - "\t \"media\" : terminal media object management\n" - "\t \"scene\" : scene graph and scene manager\n" - "\t \"script\" : scripting engine messages\n" - "\t \"interact\" : interaction engine (events, scripts, etc)\n" - "\t \"compose\" : composition engine (2D, 3D, etc)\n" - "\t \"service\" : network service management\n" - "\t \"mmio\" : Audio/Video HW I/O management\n" - "\t \"none\" : no tool logged\n" - "\t \"all\" : all tools logged\n" - "\n" - "\t-size WxH: specifies visual size (default: scene size)\n" - "\t-scale s: scales the visual size (default: 1)\n" -#if defined(__DARWIN__) || defined(__APPLE__) - "\t-thread: enables thread usage for terminal and compositor \n" -#else - "\t-no-thread: disables thread usage (except for audio)\n" -#endif - "\t-no-audio: disables audio \n" - "\t-no-wnd: uses windowless mode (Win32 only)\n" - "\t-align vh: specifies v and h alignment for windowless mode\n" - " possible v values: t(op), m(iddle), b(ottom)\n" - " possible h values: l(eft), m(iddle), r(ight)\n" - " default alignment is top-left\n" - " default alignment is top-left\n" - "\t-pause: pauses at first frame\n" - "\n" - "Dumper Options:\n" - "\t-bmp [times]: dumps given frames to bmp\n" - "\t-raw [times]: dumps given frames to bmp\n" - "\t-avi [times]: dumps given file to raw avi\n" - "\t-rgbds: dumps the RGBDS pixel format texture\n" - " with -avi [times]: dumps an rgbds-format .avi\n" - "\t-rgbd: dumps the RGBD pixel format texture\n" - " with -avi [times]: dumps an rgbd-format .avi\n" - "\t-depth: dumps depthmap (z-buffer) frames\n" - " with -avi [times]: dumps depthmap in grayscale .avi\n" - " with -bmp: dumps depthmap in grayscale .bmp\n" - "\t-fps FPS: specifies frame rate for AVI dumping (default: 25.0)\n" - "\t-2d: uses 2D compositor\n" - "\t-3d: uses 3D compositor\n" - "\t-fill: uses fill aspect ratio for dumping (default: none)\n" - "\t-show: show window while dumping (default: no)\n" - "MP4Client - GPAC command line player and dumper - version %s\n" - "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n", - - GPAC_FULL_VERSION - ); -} - -void PrintHelp() -{ - fprintf(stdout, "MP4Client command keys:\n" - "\to: connect to the specified URL\n" - "\tO: connect to the specified URL in playlist mode\n" - "\tN: switch to the next URL in the playlist (works with return key as well)\n" - "\tr: restart current presentation\n" - "\tp: play/pause the presentation\n" - "\ts: step one frame ahead\n" - "\tz: seek into presentation\n" - "\tt: print current timing\n" - "\n" - "\tw: view world info\n" - "\tv: view Object Descriptor list\n" - "\ti: view Object Descriptor info (by ID)\n" - "\tj: view Object Descriptor info (by number)\n" - "\tb: view media objects timing and buffering info\n" - "\tm: view media objects buffering and memory info\n" - "\td: dumps scene graph\n" - "\n" - "\tC: Enable Streaming Cache\n" - "\tS: Stops Streaming Cache and save to file\n" - "\tA: Aborts Streaming Cache\n" - "\n" - "\tk: turns stress mode on/off\n" - "\tn: changes navigation mode\n" - "\tx: reset to last active viewpoint\n" - "\n" - "\t2: restart using 2D compositor\n" - "\t3: restart using 3D compositor\n" - "\n" - "\t4: forces 4/3 Aspect Ratio\n" - "\t5: forces 16/9 Aspect Ratio\n" - "\t6: forces no Aspect Ratio (always fill screen)\n" - "\t7: forces original Aspect Ratio (default)\n" - "\n" - "\tL: changes to new log level. CF MP4Client usage for possible values\n" - "\tT: select new tools to log. CF MP4Client usage for possible values\n" - "\n" - "\tl: list available modules\n" - "\tc: prints some GPAC configuration info\n" - "\tR: toggles run-time info display on/off\n" - "\tq: exit the application\n" - "\th: print this message\n" - "\n" - "MP4Client - GPAC command line player - version %s\n" - "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n", - - GPAC_FULL_VERSION - ); -} - - -static void PrintTime(u64 time) -{ - u32 ms, h, m, s; - h = (u32) (time / 1000 / 3600); - m = (u32) (time / 1000 / 60 - h*60); - s = (u32) (time / 1000 - h*3600 - m*60); - ms = (u32) (time - (h*3600 + m*60 + s) * 1000); - fprintf(stdout, "%02d:%02d:%02d.%02d", h, m, s, ms); -} - - -static u32 rti_update_time_ms = 200; -static FILE *rti_logs = NULL; -static u64 memory_at_gpac_startup = 0; - -static void UpdateRTInfo(const char *legend) -{ - GF_SystemRTInfo rti; - - /*refresh every second*/ - if (!display_rti && !rti_logs) return; - if (!gf_sys_get_rti(rti_update_time_ms, &rti, 0) && !legend) - return; - - if (display_rti) { - if (!rti.process_memory) rti.process_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail); - if (!rti.gpac_memory) rti.gpac_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail); - - if (display_rti==2) { - fprintf(stdout, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB\r", - gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) ); - } else { - char szMsg[1024]; - GF_Event evt; - - sprintf(szMsg, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB", - gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) ); - evt.type = GF_EVENT_SET_CAPTION; - evt.caption.caption = szMsg; - gf_term_user_event(term, &evt); - } - } - if (rti_logs) { - fprintf(rti_logs, "% 8d\t% 8d\t% 8d\t% 4d\t% 8d\t%s", - gf_sys_clock(), - gf_term_get_time_in_ms(term), - rti.total_cpu_usage, - (u32) gf_term_get_framerate(term, 0), - (u32) (rti.gpac_memory / 1024), - legend ? legend : "" - ); - if (!legend) fprintf(rti_logs, "\n"); - } -} - -static void ResetCaption() -{ - GF_Event event; - if (display_rti) return; - event.type = GF_EVENT_SET_CAPTION; - if (is_connected) { - char szName[1024]; - NetInfoCommand com; - - event.caption.caption = NULL; - /*get any service info*/ - if (!startup_file && gf_term_get_service_info(term, gf_term_get_root_object(term), &com) == GF_OK) { - strcpy(szName, ""); - if (com.track_info) { - char szBuf[10]; - sprintf(szBuf, "%02d ", (u32) (com.track_info>>16) ); - strcat(szName, szBuf); - } - if (com.artist) { strcat(szName, com.artist); strcat(szName, " "); } - if (com.name) { strcat(szName, com.name); strcat(szName, " "); } - if (com.album) { strcat(szName, "("); strcat(szName, com.album); strcat(szName, ")"); } - - if (strlen(szName)) event.caption.caption = szName; - } - if (!event.caption.caption) { - char *str = strrchr(the_url, '\\'); - if (!str) str = strrchr(the_url, '/'); - event.caption.caption = str ? str+1 : the_url; - } - } else { - event.caption.caption = "GPAC MP4Client " GPAC_FULL_VERSION; - } - gf_term_user_event(term, &event); -} - -#ifdef WIN32 -u32 get_sys_col(int idx) -{ - u32 res; - DWORD val = GetSysColor(idx); - res = (val)&0xFF; res<<=8; - res |= (val>>8)&0xFF; res<<=8; - res |= (val>>16)&0xFF; - return res; -} -#endif - -void switch_bench() -{ - if (is_connected) { - bench_mode = !bench_mode; - display_rti = !display_rti; - ResetCaption(); - gf_term_set_speed(term, bench_mode ? bench_speed : FIX_ONE); - } -} - -Bool GPAC_EventProc(void *ptr, GF_Event *evt) -{ - if (!term) return 0; - - switch (evt->type) { - case GF_EVENT_DURATION: - Duration = 1000; - Duration = (u64) (((s64) Duration) * evt->duration.duration); - CanSeek = evt->duration.can_seek; - break; - case GF_EVENT_MESSAGE: - { - const char *servName; - if (!evt->message.service || !strcmp(evt->message.service, the_url)) { - servName = "main service"; - } else if (!strnicmp(evt->message.service, "data:", 5)) { - servName = ""; - } else { - servName = evt->message.service; - } - if (!evt->message.message) return 0; - if (evt->message.error) { - if (!is_connected) last_error = evt->message.error; - fprintf(stderr, "%s (%s): %s\n", evt->message.message, servName, gf_error_to_string(evt->message.error)); - } else if (!be_quiet) - fprintf(stderr, "(%s) %s\r", servName, evt->message.message); - } - break; - case GF_EVENT_PROGRESS: - { - char *szTitle = ""; - if (evt->progress.progress_type==0) szTitle = "Buffer "; - else if (evt->progress.progress_type==1) szTitle = "Download "; - else if (evt->progress.progress_type==2) szTitle = "Import "; - gf_set_progress(szTitle, evt->progress.done, evt->progress.total); - } - break; - - - case GF_EVENT_DBLCLICK: - gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN)); - return 0; - - case GF_EVENT_MOUSEDOWN: - if (evt->mouse.button==GF_MOUSE_RIGHT) { - right_down = 1; - last_x = evt->mouse.x; - last_y = evt->mouse.y; - } - return 0; - case GF_EVENT_MOUSEUP: - if (evt->mouse.button==GF_MOUSE_RIGHT) { - right_down = 0; - last_x = evt->mouse.x; - last_y = evt->mouse.y; - } - return 0; - case GF_EVENT_MOUSEMOVE: - if (right_down && (user.init_flags & GF_TERM_WINDOWLESS) ) { - GF_Event move; - move.move.x = evt->mouse.x - last_x; - move.move.y = last_y-evt->mouse.y; - move.type = GF_EVENT_MOVE; - move.move.relative = 1; - gf_term_user_event(term, &move); - } - return 0; - - case GF_EVENT_KEYUP: - switch (evt->key.key_code) { - case GF_KEY_SPACE: - if (evt->key.flags & GF_KEY_MOD_CTRL) switch_bench(); - break; - } - break; - case GF_EVENT_KEYDOWN: - gf_term_process_shortcut(term, evt); - switch (evt->key.key_code) { - case GF_KEY_SPACE: - if (evt->key.flags & GF_KEY_MOD_CTRL) { - /*ignore key repeat*/ - if (!bench_mode) switch_bench(); - } - break; - case GF_KEY_PAGEDOWN: - case GF_KEY_MEDIANEXTTRACK: - request_next_playlist_item = 1; - break; - case GF_KEY_MEDIAPREVIOUSTRACK: - break; - case GF_KEY_ESCAPE: - gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN)); - break; - case GF_KEY_F: - if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stderr, "Rendering rate: %f FPS\n", gf_term_get_framerate(term, 0)); - break; - case GF_KEY_T: - if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stderr, "Scene Time: %f \n", gf_term_get_time_in_ms(term)/1000.0); - break; - case GF_KEY_D: - if (evt->key.flags & GF_KEY_MOD_CTRL) gf_term_set_option(term, GF_OPT_DRAW_MODE, (gf_term_get_option(term, GF_OPT_DRAW_MODE)==GF_DRAW_MODE_DEFER) ? GF_DRAW_MODE_IMMEDIATE : GF_DRAW_MODE_DEFER ); - break; - case GF_KEY_4: - if (evt->key.flags & GF_KEY_MOD_CTRL) - gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); - break; - case GF_KEY_5: - if (evt->key.flags & GF_KEY_MOD_CTRL) - gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); - break; - case GF_KEY_6: - if (evt->key.flags & GF_KEY_MOD_CTRL) - gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); - break; - case GF_KEY_7: - if (evt->key.flags & GF_KEY_MOD_CTRL) - gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); - break; - case GF_KEY_P: - if (evt->key.flags & GF_KEY_MOD_CTRL && is_connected) { - Bool is_pause = gf_term_get_option(term, GF_OPT_PLAY_STATE); - fprintf(stderr, "[Status: %s]\n", is_pause ? "Playing" : "Paused"); - gf_term_set_option(term, GF_OPT_PLAY_STATE, (gf_term_get_option(term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) ? GF_STATE_PLAYING : GF_STATE_PAUSED); - } - break; - case GF_KEY_S: - if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) { - gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); - fprintf(stderr, "Step time: "); - PrintTime(gf_term_get_time_in_ms(term)); - fprintf(stderr, "\n"); - } - break; - case GF_KEY_B: - if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) - ViewODs(term, 1); - break; - case GF_KEY_M: - if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) - ViewODs(term, 0); - break; - case GF_KEY_H: - if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) - gf_term_switch_quality(term, 1); - break; - case GF_KEY_L: - if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) - gf_term_switch_quality(term, 0); - break; - } - break; - - case GF_EVENT_CONNECT: - if (evt->connect.is_connected) { - is_connected = 1; - fprintf(stderr, "Service Connected\n"); - } else if (is_connected) { - fprintf(stderr, "Service %s\n", is_connected ? "Disconnected" : "Connection Failed"); - is_connected = 0; - Duration = 0; - } - if (init_w && init_h) { - gf_term_set_size(term, init_w, init_h); - } - ResetCaption(); - break; - case GF_EVENT_EOS: - restart = 1; - break; - case GF_EVENT_SIZE: - if (user.init_flags & GF_TERM_WINDOWLESS) { - GF_Event move; - move.type = GF_EVENT_MOVE; - move.move.align_x = align_mode & 0xFF; - move.move.align_y = (align_mode>>8) & 0xFF; - move.move.relative = 2; - gf_term_user_event(term, &move); - } - break; - case GF_EVENT_SCENE_SIZE: - if (forced_width && forced_height) { - GF_Event size; - size.type = GF_EVENT_SIZE; - size.size.width = forced_width; - size.size.height = forced_height; - gf_term_user_event(term, &size); - } - break; - - case GF_EVENT_METADATA: - ResetCaption(); - break; - - case GF_EVENT_QUIT: - Run = 0; - break; - case GF_EVENT_DISCONNECT: - gf_term_disconnect(term); - break; - case GF_EVENT_MIGRATE: - { - } - break; - case GF_EVENT_NAVIGATE_INFO: - if (evt->navigate.to_url) fprintf(stderr, "Go to URL: \"%s\"\r", evt->navigate.to_url); - break; - case GF_EVENT_NAVIGATE: - if (gf_term_is_supported_url(term, evt->navigate.to_url, 1, no_mime_check)) { - strcpy(the_url, evt->navigate.to_url); - fprintf(stderr, "Navigating to URL %s\n", the_url); - gf_term_navigate_to(term, evt->navigate.to_url); - return 1; - } else { - fprintf(stderr, "Navigation destination not supported\nGo to URL: %s\n", evt->navigate.to_url); - } - break; - case GF_EVENT_SET_CAPTION: - gf_term_user_event(term, evt); - break; - case GF_EVENT_AUTHORIZATION: - if (!strlen(evt->auth.user)) { - fprintf(stderr, "Authorization required for site %s\n", evt->auth.site_url); - fprintf(stderr, "login: "); - scanf("%s", evt->auth.user); - } else { - fprintf(stderr, "Authorization required for %s@%s\n", evt->auth.user, evt->auth.site_url); - } - fprintf(stderr, "password: "); - gf_prompt_set_echo_off(1); - scanf("%s", evt->auth.password); - gf_prompt_set_echo_off(0); - return 1; - case GF_EVENT_SYS_COLORS: -#ifdef WIN32 - evt->sys_cols.sys_colors[0] = get_sys_col(COLOR_ACTIVEBORDER); - evt->sys_cols.sys_colors[1] = get_sys_col(COLOR_ACTIVECAPTION); - evt->sys_cols.sys_colors[2] = get_sys_col(COLOR_APPWORKSPACE); - evt->sys_cols.sys_colors[3] = get_sys_col(COLOR_BACKGROUND); - evt->sys_cols.sys_colors[4] = get_sys_col(COLOR_BTNFACE); - evt->sys_cols.sys_colors[5] = get_sys_col(COLOR_BTNHIGHLIGHT); - evt->sys_cols.sys_colors[6] = get_sys_col(COLOR_BTNSHADOW); - evt->sys_cols.sys_colors[7] = get_sys_col(COLOR_BTNTEXT); - evt->sys_cols.sys_colors[8] = get_sys_col(COLOR_CAPTIONTEXT); - evt->sys_cols.sys_colors[9] = get_sys_col(COLOR_GRAYTEXT); - evt->sys_cols.sys_colors[10] = get_sys_col(COLOR_HIGHLIGHT); - evt->sys_cols.sys_colors[11] = get_sys_col(COLOR_HIGHLIGHTTEXT); - evt->sys_cols.sys_colors[12] = get_sys_col(COLOR_INACTIVEBORDER); - evt->sys_cols.sys_colors[13] = get_sys_col(COLOR_INACTIVECAPTION); - evt->sys_cols.sys_colors[14] = get_sys_col(COLOR_INACTIVECAPTIONTEXT); - evt->sys_cols.sys_colors[15] = get_sys_col(COLOR_INFOBK); - evt->sys_cols.sys_colors[16] = get_sys_col(COLOR_INFOTEXT); - evt->sys_cols.sys_colors[17] = get_sys_col(COLOR_MENU); - evt->sys_cols.sys_colors[18] = get_sys_col(COLOR_MENUTEXT); - evt->sys_cols.sys_colors[19] = get_sys_col(COLOR_SCROLLBAR); - evt->sys_cols.sys_colors[20] = get_sys_col(COLOR_3DDKSHADOW); - evt->sys_cols.sys_colors[21] = get_sys_col(COLOR_3DFACE); - evt->sys_cols.sys_colors[22] = get_sys_col(COLOR_3DHIGHLIGHT); - evt->sys_cols.sys_colors[23] = get_sys_col(COLOR_3DLIGHT); - evt->sys_cols.sys_colors[24] = get_sys_col(COLOR_3DSHADOW); - evt->sys_cols.sys_colors[25] = get_sys_col(COLOR_WINDOW); - evt->sys_cols.sys_colors[26] = get_sys_col(COLOR_WINDOWFRAME); - evt->sys_cols.sys_colors[27] = get_sys_col(COLOR_WINDOWTEXT); - return 1; -#else - memset(evt->sys_cols.sys_colors, 0, sizeof(u32)*28); - return 1; -#endif - break; - } - return 0; -} - - -void list_modules(GF_ModuleManager *modules) -{ - u32 i; - fprintf(stderr, "\rAvailable modules:\n"); - for (i=0; isimulation_time)) { - Run = 0; - } - continue; - } - c = gf_prompt_get_char(); - -force_input: - switch (c) { - case 'q': - Run = 0; - break; - case 'X': - exit(0); - break; - case 'Q': - break; - case 'o': - startup_file = 0; - gf_term_disconnect(term); - fprintf(stdout, "Enter the absolute URL\n"); - scanf("%s", the_url); - if (rti_file) init_rti_logs(rti_file, the_url, use_rtix); - gf_term_connect(term, the_url); - break; - case 'O': - gf_term_disconnect(term); - fprintf(stdout, "Enter the absolute URL to the playlist\n"); - scanf("%s", the_url); - playlist = gf_f64_open(the_url, "rt"); - if (playlist) { - fscanf(playlist, "%s", the_url); - fprintf(stdout, "Opening URL %s\n", the_url); - gf_term_connect(term, the_url); - } - break; - case '\n': - case 'N': - if (playlist) { - gf_term_disconnect(term); - - if (fscanf(playlist, "%s", the_url) == EOF) { - fprintf(stdout, "No more items - exiting\n"); - Run = 0; - } else { - fprintf(stdout, "Opening URL %s\n", the_url); - gf_term_connect_with_path(term, the_url, pl_path); - } - } - break; - case 'P': - if (playlist) { - u32 count; - gf_term_disconnect(term); - scanf("%d", &count); - while (count) { - fscanf(playlist, "%s", the_url); - count--; - } - fprintf(stdout, "Opening URL %s\n", the_url); - gf_term_connect(term, the_url); - } - break; - case 'r': - if (is_connected) { - gf_term_disconnect(term); - gf_term_connect(term, startup_file ? gf_cfg_get_key(cfg_file, "General", "StartupFile") : the_url); - } - break; - - case 'D': - if (is_connected) gf_term_disconnect(term); - break; - - case 'p': - if (is_connected) { - Bool is_pause = gf_term_get_option(term, GF_OPT_PLAY_STATE); - fprintf(stdout, "[Status: %s]\n", is_pause ? "Playing" : "Paused"); - gf_term_set_option(term, GF_OPT_PLAY_STATE, is_pause ? GF_STATE_PLAYING : GF_STATE_PAUSED); - } - break; - case 's': - if (is_connected) { - gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); - fprintf(stdout, "Step time: "); - PrintTime(gf_term_get_time_in_ms(term)); - fprintf(stdout, "\n"); - } - break; - - case 'z': - if (!CanSeek || (Duration<=2000)) { - fprintf(stdout, "scene not seekable\n"); - } else { - Double res; - s32 seekTo; - fprintf(stdout, "Duration: "); - PrintTime(Duration); - res = gf_term_get_time_in_ms(term); - res *= 100; res /= (s64)Duration; - fprintf(stdout, " (current %.2f %%)\nEnter Seek percentage:\n", res); - if (scanf("%d", &seekTo) == 1) { - if (seekTo > 100) seekTo = 100; - res = (Double)(s64)Duration; res /= 100; res *= seekTo; - gf_term_play_from_time(term, (u64) (s64) res, 0); - } - } - break; - - case 't': - { - if (is_connected) { - fprintf(stdout, "Current Time: "); - PrintTime(gf_term_get_time_in_ms(term)); - fprintf(stdout, " - Duration: "); - PrintTime(Duration); - fprintf(stdout, "\n"); - } - } - break; - case 'w': - if (is_connected) PrintWorldInfo(term); - break; - case 'v': - if (is_connected) PrintODList(term, NULL, 0, 0, "Root"); - break; - case 'i': - if (is_connected) { - u32 ID; - fprintf(stdout, "Enter OD ID (0 for main OD): "); - fflush(stdout); - scanf("%d", &ID); - ViewOD(term, ID, (u32)-1); - } - break; - case 'j': - if (is_connected) { - u32 num; - fprintf(stdout, "Enter OD number (0 for main OD): "); - fflush(stdout); - scanf("%d", &num); - ViewOD(term, (u32)-1, num); - } - break; - case 'b': - if (is_connected) ViewODs(term, 1); - break; - - case 'm': - if (is_connected) ViewODs(term, 0); - break; - - case 'l': - list_modules(user.modules); - break; - - case 'n': - if (is_connected) set_navigation(); - break; - case 'x': - if (is_connected) gf_term_set_option(term, GF_OPT_NAVIGATION_TYPE, 0); - break; - - case 'd': - if (is_connected) { - GF_ObjectManager *odm = NULL; - char radname[GF_MAX_PATH], *sExt; - GF_Err e; - u32 i, count, odid; - Bool xml_dump, std_out; - fprintf(stdout, "Enter Inline OD ID if any or 0"); - fflush(stdout); - radname[0] = 0; - scanf("%d", &odid); - if (odid) { - GF_ObjectManager *root_odm = gf_term_get_root_object(term); - if (!root_odm) break; - count = gf_term_get_object_count(term, root_odm); - for (i=0; iobjectDescriptorID==odid) break; - } - odm = NULL; - } - } - fprintf(stdout, "Enter file radical name (+\'.x\' for XML dumping) - \"std\" for stdout: "); - fflush(stdout); - scanf("%s", radname); - sExt = strrchr(radname, '.'); - xml_dump = 0; - if (sExt) { - if (!stricmp(sExt, ".x")) xml_dump = 1; - sExt[0] = 0; - } - std_out = strnicmp(radname, "std", 3) ? 0 : 1; - e = gf_term_dump_scene(term, std_out ? NULL : radname, NULL, xml_dump, 0, odm); - fprintf(stdout, "Dump done (%s)\n", gf_error_to_string(e)); - } - break; - - case 'c': - PrintGPACConfig(); - break; - case '3': - { - Bool use_3d = !gf_term_get_option(term, GF_OPT_USE_OPENGL); - if (gf_term_set_option(term, GF_OPT_USE_OPENGL, use_3d)==GF_OK) { - fprintf(stdout, "Using %s for 2D drawing\n", use_3d ? "OpenGL" : "2D rasterizer"); - } - } - break; - case 'k': - { - Bool opt = gf_term_get_option(term, GF_OPT_STRESS_MODE); - opt = !opt; - fprintf(stdout, "Turning stress mode %s\n", opt ? "on" : "off"); - gf_term_set_option(term, GF_OPT_STRESS_MODE, opt); - } - break; - case '4': gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); break; - case '5': gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); break; - case '6': gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); break; - case '7': gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); break; - - case 'C': - switch (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)) { - case GF_MEDIA_CACHE_DISABLED: gf_term_set_option(term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_ENABLED); break; - case GF_MEDIA_CACHE_ENABLED: gf_term_set_option(term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); break; - case GF_MEDIA_CACHE_RUNNING: fprintf(stdout, "Streaming Cache is running - please stop it first\n"); continue; - } - switch (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)) { - case GF_MEDIA_CACHE_ENABLED: fprintf(stdout, "Streaming Cache Enabled\n"); break; - case GF_MEDIA_CACHE_DISABLED: fprintf(stdout, "Streaming Cache Disabled\n"); break; - case GF_MEDIA_CACHE_RUNNING: fprintf(stdout, "Streaming Cache Running\n"); break; - } - break; - case 'S': - case 'A': - if (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)==GF_MEDIA_CACHE_RUNNING) { - gf_term_set_option(term, GF_OPT_MEDIA_CACHE, (c=='S') ? GF_MEDIA_CACHE_DISABLED : GF_MEDIA_CACHE_DISCARD); - fprintf(stdout, "Streaming Cache stopped\n"); - } else { - fprintf(stdout, "Streaming Cache not running\n"); - } - break; - case 'R': - display_rti = !display_rti; - ResetCaption(); - break; - case 'F': - if (display_rti) display_rti = 0; - else display_rti = 2; - ResetCaption(); - break; - - case 'u': - { - GF_Err e; - char szCom[8192]; - fprintf(stdout, "Enter command to send:\n"); - fflush(stdin); - szCom[0] = 0; - scanf("%[^\t\n]", szCom); - e = gf_term_scene_update(term, NULL, szCom); - if (e) fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e)); - } - break; - - case 'L': - { - char szLog[1024]; - fprintf(stdout, "Enter new log level:\n"); - scanf("%s", szLog); - gf_log_modify_tools_levels( szLog ); - } - break; - case 'g': - { - GF_SystemRTInfo rti; - gf_sys_get_rti(rti_update_time_ms, &rti, 0); - fprintf(stdout, "GPAC allocated memory "LLD"\n", rti.gpac_memory); - } - break; - case 'M': - { - u32 size; - fprintf(stdout, "Enter new video cache memory in kBytes (current %d):\n", gf_term_get_option(term, GF_OPT_VIDEO_CACHE_SIZE)); - scanf("%d", &size); - gf_term_set_option(term, GF_OPT_VIDEO_CACHE_SIZE, size); - } - break; - - case 'E': - gf_term_set_option(term, GF_OPT_RELOAD_CONFIG, 1); - break; - - case 'B': - switch_bench(); - break; - - /*extract to PNG*/ - case 'Z': - { - GF_VideoSurface fb; - GF_Err e; - e = gf_term_get_screen_buffer(term, &fb); - if (e) { - fprintf(stdout, "Error dumping screen buffer %s\n", gf_error_to_string(e) ); - } else { - u32 dst_size = fb.width*fb.height*3; - char *dst=malloc(sizeof(char)*dst_size); - - e = gf_img_png_enc(fb.video_buffer, fb.width, fb.height, fb.pitch_y, fb.pixel_format, dst, &dst_size); - if (e) { - fprintf(stdout, "Error encoding PNG %s\n", gf_error_to_string(e) ); - } else { - FILE *png = gf_f64_open("dump.png", "wb"); - if (!png) { - fprintf(stdout, "Error writing file dump.png\n"); - } else { - gf_fwrite(dst, dst_size, 1, png); - fclose(png); - fprintf(stdout, "Writing file dump.png\n"); - } - } - if (dst) free(dst); - gf_term_release_screen_buffer(term, &fb); - } - } - break; - - case 'h': - PrintHelp(); - break; - default: - break; - } - } - - gf_term_disconnect(term); - if (rti_file) UpdateRTInfo("Disconnected\n"); - - fprintf(stdout, "Deleting terminal... "); - if (playlist) fclose(playlist); - gf_term_del(term); - fprintf(stdout, "OK\n"); - - fprintf(stdout, "GPAC cleanup ...\n"); - gf_modules_del(user.modules); - gf_cfg_del(cfg_file); - -#ifdef GPAC_MEMORY_TRACKING - if (enable_mem_tracker) { - gf_memory_print(); - fprintf(stdout, "print any key\n"); - while (!gf_prompt_has_input()) { - gf_sleep(100); - } - } -#endif - - gf_sys_close(); - if (rti_logs) fclose(rti_logs); - if (logfile) fclose(logfile); - fprintf(stdout, "Bye\n"); - return 0; -} - -void PrintWorldInfo(GF_Terminal *term) -{ - u32 i; - const char *title; - GF_List *descs; - descs = gf_list_new(); - title = gf_term_get_world_info(term, NULL, descs); - if (!title && !gf_list_count(descs)) { - fprintf(stdout, "No World Info available\n"); - } else { - fprintf(stdout, "\t%s\n", title ? title : "No title available"); - for (i=0; iobjectDescriptorID); - } - - szIndent[indent]=' '; - szIndent[indent+1]=0; - indent++; - - count = gf_term_get_object_count(term, root_odm); - for (i=0; iobjectDescriptorID); - } - fprintf(stdout, " - %s\n", (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems"); - break; - } - } - } -} - -void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number) -{ - GF_MediaInfo odi; - u32 i, j, count, d_enum,id; - GF_Err e; - char code[5]; - NetStatCommand com; - GF_ObjectManager *odm, *root_odm = gf_term_get_root_object(term); - if (!root_odm) return; - - odm = NULL; - if ((!OD_ID && (number == (u32)(-1))) || - ((OD_ID == (u32)(-1)) && !number)) { - odm = root_odm; - if ((gf_term_get_object_info(term, odm, &odi) != GF_OK)) odm=NULL; - } else { - count = gf_term_get_object_count(term, root_odm); - for (i=0; iobjectDescriptorID == OD_ID)) break; - else if (i == (u32)(number-1)) break; - } - odm = NULL; - } - } - if (!odm) { - if (number == (u32)-1) fprintf(stdout, "cannot find OD with ID %d\n", OD_ID); - else fprintf(stdout, "cannot find OD with number %d\n", number); - return; - } - if (!odi.od) { - if (number == (u32)-1) fprintf(stdout, "Object %d not attached yet\n", OD_ID); - else fprintf(stdout, "Object #%d not attached yet\n", number); - return; - } - - if (!odi.od) { - fprintf(stdout, "Service not attached\n"); - return; - } - - if (odi.od->tag==GF_ODF_IOD_TAG) { - fprintf(stdout, "InitialObjectDescriptor %d\n", odi.od->objectDescriptorID); - fprintf(stdout, "Profiles and Levels: Scene %x - Graphics %x - Visual %x - Audio %x - OD %x\n", - odi.scene_pl, odi.graphics_pl, odi.visual_pl, odi.audio_pl, odi.OD_pl); - fprintf(stdout, "Inline Profile Flag %d\n", odi.inline_pl); - } else { - fprintf(stdout, "ObjectDescriptor %d\n", odi.od->objectDescriptorID); - } - - fprintf(stdout, "Object Duration: "); - if (odi.duration) { - PrintTime((u32) (odi.duration*1000)); - } else { - fprintf(stdout, "unknown"); - } - fprintf(stdout, "\n"); - - if (odi.owns_service) { - fprintf(stdout, "Service Handler: %s\n", odi.service_handler); - fprintf(stdout, "Service URL: %s\n", odi.service_url); - } - if (odi.codec_name) { - Float avg_dec_time; - switch (odi.od_type) { - case GF_STREAM_VISUAL: - fprintf(stdout, "Video Object: Width %d - Height %d\r\n", odi.width, odi.height); - fprintf(stdout, "Media Codec: %s\n", odi.codec_name); - if (odi.par) fprintf(stdout, "Pixel Aspect Ratio: %d:%d\n", (odi.par>>16)&0xFF, (odi.par)&0xFF); - break; - case GF_STREAM_AUDIO: - fprintf(stdout, "Audio Object: Sample Rate %d - %d channels\r\n", odi.sample_rate, odi.num_channels); - fprintf(stdout, "Media Codec: %s\n", odi.codec_name); - break; - case GF_STREAM_SCENE: - case GF_STREAM_PRIVATE_SCENE: - if (odi.width && odi.height) { - fprintf(stdout, "Scene Description - Width %d - Height %d\n", odi.width, odi.height); - } else { - fprintf(stdout, "Scene Description - no size specified\n"); - } - fprintf(stdout, "Scene Codec: %s\n", odi.codec_name); - break; - case GF_STREAM_TEXT: - if (odi.width && odi.height) { - fprintf(stdout, "Text Object: Width %d - Height %d\n", odi.width, odi.height); - } else { - fprintf(stdout, "Text Object: No size specified\n"); - } - fprintf(stdout, "Text Codec %s\n", odi.codec_name); - break; - } - - avg_dec_time = 0; - if (odi.nb_dec_frames) { - avg_dec_time = (Float) odi.total_dec_time; - avg_dec_time /= odi.nb_dec_frames; - } - fprintf(stdout, "\tBitrate over last second: %d kbps\n\tMax bitrate over one second: %d kbps\n\tAverage Decoding Time %.2f ms (%d max)\n\tTotal decoded frames %d\n", - (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time, odi.nb_dec_frames); - } - if (odi.protection) fprintf(stdout, "Encrypted Media%s\n", (odi.protection==2) ? " NOT UNLOCKED" : ""); - - count = gf_list_count(odi.od->ESDescriptors); - fprintf(stdout, "%d streams in OD\n", count); - for (i=0; iESDescriptors, i); - - fprintf(stdout, "\nStream ID %d - Clock ID %d\n", esd->ESID, esd->OCRESID); - if (esd->dependsOnESID) fprintf(stdout, "\tDepends on Stream ID %d for decoding\n", esd->dependsOnESID); - - switch (esd->decoderConfig->streamType) { - case GF_STREAM_OD: fprintf(stdout, "\tOD Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break; - case GF_STREAM_OCR: fprintf(stdout, "\tOCR Stream\n"); break; - case GF_STREAM_SCENE: fprintf(stdout, "\tScene Description Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break; - case GF_STREAM_VISUAL: - fprintf(stdout, "\tVisual Stream - media type: "); - switch (esd->decoderConfig->objectTypeIndication) { - case GPAC_OTI_VIDEO_MPEG4_PART2: fprintf(stdout, "MPEG-4\n"); break; - case GPAC_OTI_VIDEO_MPEG2_SIMPLE: fprintf(stdout, "MPEG-2 Simple Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_MAIN: fprintf(stdout, "MPEG-2 Main Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_SNR: fprintf(stdout, "MPEG-2 SNR Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_SPATIAL: fprintf(stdout, "MPEG-2 Spatial Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_HIGH: fprintf(stdout, "MPEG-2 High Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_422: fprintf(stdout, "MPEG-2 422 Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG1: fprintf(stdout, "MPEG-1\n"); break; - case GPAC_OTI_IMAGE_JPEG: fprintf(stdout, "JPEG\n"); break; - case GPAC_OTI_IMAGE_PNG: fprintf(stdout, "PNG\n"); break; - case GPAC_OTI_IMAGE_JPEG_2000: fprintf(stdout, "JPEG2000\n"); break; - - case GPAC_OTI_MEDIA_GENERIC: - memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); - code[4] = 0; - fprintf(stdout, "GPAC Intern (%s)\n", code); - break; - default: - fprintf(stdout, "Private Type (0x%x)\n", esd->decoderConfig->objectTypeIndication); - break; - } - break; - - case GF_STREAM_AUDIO: - fprintf(stdout, "\tAudio Stream - media type: "); - switch (esd->decoderConfig->objectTypeIndication) { - case GPAC_OTI_AUDIO_AAC_MPEG4: fprintf(stdout, "MPEG-4\n"); break; - case GPAC_OTI_AUDIO_AAC_MPEG2_MP: fprintf(stdout, "MPEG-2 AAC Main Profile\n"); break; - case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: fprintf(stdout, "MPEG-2 AAC LowComplexity Profile\n"); break; - case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: fprintf(stdout, "MPEG-2 AAC Scalable Sampling Rate Profile\n"); break; - case GPAC_OTI_AUDIO_MPEG2_PART3: fprintf(stdout, "MPEG-2 Audio\n"); break; - case GPAC_OTI_AUDIO_MPEG1: fprintf(stdout, "MPEG-1 Audio\n"); break; - case GPAC_OTI_AUDIO_EVRC_VOICE: fprintf(stdout, "EVRC Audio\n"); break; - case GPAC_OTI_AUDIO_SMV_VOICE: fprintf(stdout, "SMV Audio\n"); break; - case GPAC_OTI_AUDIO_13K_VOICE: fprintf(stdout, "QCELP Audio\n"); break; - case GPAC_OTI_MEDIA_GENERIC: - memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); - code[4] = 0; - fprintf(stdout, "GPAC Intern (%s)\n", code); - break; - default: - fprintf(stdout, "Private Type (0x%x)\n", esd->decoderConfig->objectTypeIndication); - break; - } - break; - case GF_STREAM_MPEG7: fprintf(stdout, "\tMPEG-7 Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break; - case GF_STREAM_IPMP: fprintf(stdout, "\tIPMP Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break; - case GF_STREAM_OCI: fprintf(stdout, "\tOCI Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break; - case GF_STREAM_MPEGJ: fprintf(stdout, "\tMPEGJ Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break; - case GF_STREAM_INTERACT: fprintf(stdout, "\tUser Interaction Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break; - case GF_STREAM_TEXT: fprintf(stdout, "\tStreaming Text Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break; - default: fprintf(stdout, "Unknown Stream\r\n"); break; - } - - fprintf(stdout, "\tBuffer Size %d\n\tAverage Bitrate %d bps\n\tMaximum Bitrate %d bps\n", esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate, esd->decoderConfig->maxBitrate); - if (esd->slConfig->predefined==SLPredef_SkipSL) { - fprintf(stdout, "\tNot using MPEG-4 Synchronization Layer\n"); - } else { - fprintf(stdout, "\tStream Clock Resolution %d\n", esd->slConfig->timestampResolution); - } - if (esd->URLString) fprintf(stdout, "\tStream Location: %s\n", esd->URLString); - - /*check language*/ - if (esd->langDesc) { - u32 i=0; - char lan[4], *szLang; - lan[0] = esd->langDesc->langCode>>16; - lan[1] = (esd->langDesc->langCode>>8)&0xFF; - lan[2] = (esd->langDesc->langCode)&0xFF; - lan[3] = 0; - - if ((lan[0]=='u') && (lan[1]=='n') && (lan[2]=='d')) szLang = "Undetermined"; - else { - szLang = lan; - while (GF_ISO639_Lang[i]) { - if (GF_ISO639_Lang[i+2][0] && strstr(GF_ISO639_Lang[i+1], lan)) { - szLang = (char*) GF_ISO639_Lang[i]; - break; - } - i+=3; - } - } - fprintf(stdout, "\tStream Language: %s\n", szLang); - } - } - fprintf(stdout, "\n"); - /*check OCI (not everything interests us) - FIXME: support for unicode*/ - count = gf_list_count(odi.od->OCIDescriptors); - if (count) { - fprintf(stdout, "%d Object Content Information descriptors in OD\n", count); - for (i=0; iOCIDescriptors, i); - switch (desc->tag) { - case GF_ODF_SEGMENT_TAG: - { - GF_Segment *sd = (GF_Segment *) desc; - fprintf(stdout, "Segment Descriptor: Name: %s - start time %g sec - duration %g sec\n", sd->SegmentName, sd->startTime, sd->Duration); - } - break; - case GF_ODF_CC_NAME_TAG: - { - GF_CC_Name *ccn = (GF_CC_Name *)desc; - fprintf(stdout, "Content Creators:\n"); - for (j=0; jContentCreators); j++) { - GF_ContentCreatorInfo *ci = (GF_ContentCreatorInfo *) gf_list_get(ccn->ContentCreators, j); - if (!ci->isUTF8) continue; - fprintf(stdout, "\t%s\n", ci->contentCreatorName); - } - } - break; - - case GF_ODF_SHORT_TEXT_TAG: - { - GF_ShortTextual *std = (GF_ShortTextual *)desc; - fprintf(stdout, "Description:\n\tEvent: %s\n\t%s\n", std->eventName, std->eventText); - } - break; - default: - break; - } - } - fprintf(stdout, "\n"); - } - - switch (odi.status) { - case 0: fprintf(stdout, "Stopped - "); break; - case 1: fprintf(stdout, "Playing - "); break; - case 2: fprintf(stdout, "Paused - "); break; - case 3: fprintf(stdout, "Not setup yet\n"); return; - default: fprintf(stdout, "Setup Failed\n"); return; - } - if (odi.buffer>=0) fprintf(stdout, "Buffer: %d ms - ", odi.buffer); - else fprintf(stdout, "Not buffering - "); - fprintf(stdout, "Clock drift: %d ms\n", odi.clock_drift); - if (odi.db_unit_count) fprintf(stdout, "%d AU in DB\n", odi.db_unit_count); - if (odi.cb_max_count) fprintf(stdout, "Composition Buffer: %d CU (%d max)\n", odi.cb_unit_count, odi.cb_max_count); - fprintf(stdout, "\n"); - - if (odi.owns_service) { - const char *url; - u32 done, total, bps; - d_enum = 0; - while (gf_term_get_download_info(term, odm, &d_enum, &url, NULL, &done, &total, &bps)) { - if (d_enum==1) fprintf(stdout, "Current Downloads in service:\n"); - if (done && total) { - fprintf(stdout, "%s: %d / %d bytes (%.2f %%) - %.2f kBps\n", url, done, total, (100.0f*done)/total, ((Float)bps)/1024.0f); - } else { - fprintf(stdout, "%s: %.2f kbps\n", url, ((Float)8*bps)/1024.0f); - } - } - if (!d_enum) fprintf(stdout, "No Downloads in service\n"); - fprintf(stdout, "\n"); - } - d_enum = 0; - while (gf_term_get_channel_net_info(term, odm, &d_enum, &id, &com, &e)) { - if (e) continue; - if (!com.bw_down && !com.bw_up) continue; - - fprintf(stdout, "Stream ID %d statistics:\n", id); - if (com.multiplex_port) { - fprintf(stdout, "\tMultiplex Port %d - multiplex ID %d\n", com.multiplex_port, com.port); - } else { - fprintf(stdout, "\tPort %d\n", com.port); - } - fprintf(stdout, "\tPacket Loss Percentage: %.4f\n", com.pck_loss_percentage); - fprintf(stdout, "\tDown Bandwidth: %d bps\n", com.bw_down); - if (com.bw_up) fprintf(stdout, "\tUp Bandwidth: %d bps\n", com.bw_up); - if (com.ctrl_port) { - if (com.multiplex_port) { - fprintf(stdout, "\tControl Multiplex Port: %d - Control Multiplex ID %d\n", com.multiplex_port, com.ctrl_port); - } else { - fprintf(stdout, "\tControl Port: %d\n", com.ctrl_port); - } - fprintf(stdout, "\tDown Bandwidth: %d bps\n", com.ctrl_bw_down); - fprintf(stdout, "\tUp Bandwidth: %d bps\n", com.ctrl_bw_up); - } - fprintf(stdout, "\n"); - } -} - -void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm) -{ - GF_MediaInfo odi; - if (!odm) return; - - if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return; - if (!odi.od) { - fprintf(stdout, "Service not attached\n"); - return; - } - - fprintf(stdout, "OD %d: ", odi.od->objectDescriptorID); - switch (odi.status) { - case 1: fprintf(stdout, "Playing - "); break; - case 2: fprintf(stdout, "Paused - "); break; - default: fprintf(stdout, "Stopped - "); break; - } - if (odi.buffer>=0) fprintf(stdout, "Buffer: %d ms - ", odi.buffer); - else fprintf(stdout, "Not buffering - "); - fprintf(stdout, "Clock drift: %d ms", odi.clock_drift); - fprintf(stdout, " - time: "); - PrintTime((u32) (odi.current_time*1000)); - fprintf(stdout, "\n"); -} - -void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm) -{ - Float avg_dec_time; - GF_MediaInfo odi; - if (!odm) return; - - if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return; - if (!odi.od) { - fprintf(stdout, "Service not attached\n"); - return; - } - - fprintf(stdout, "OD %d: ", odi.od->objectDescriptorID); - switch (odi.status) { - case 1: fprintf(stdout, "Playing"); break; - case 2: fprintf(stdout, "Paused"); break; - default: fprintf(stdout, "Stopped"); break; - } - if (odi.buffer>=0) fprintf(stdout, " - Buffer: %d ms", odi.buffer); - if (odi.db_unit_count) fprintf(stdout, " - DB: %d AU", odi.db_unit_count); - if (odi.cb_max_count) fprintf(stdout, " - CB: %d/%d CUs", odi.cb_unit_count, odi.cb_max_count); - - fprintf(stdout, "\n * %d decoded frames - %d dropped frames\n", odi.nb_dec_frames, odi.nb_droped); - avg_dec_time = 0; - if (odi.nb_dec_frames) { avg_dec_time = (Float) odi.total_dec_time; avg_dec_time /= odi.nb_dec_frames; } - fprintf(stdout, " * Avg Bitrate %d kbps (%d max) - Avg Decoding Time %.2f ms (%d max)\n", - (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time); -} - -void ViewODs(GF_Terminal *term, Bool show_timing) -{ - u32 i, count; - GF_ObjectManager *odm, *root_odm = gf_term_get_root_object(term); - if (!root_odm) return; - - if (show_timing) { - PrintODTiming(term, root_odm); - } else { - PrintODBuffer(term, root_odm); - } - count = gf_term_get_object_count(term, root_odm); - for (i=0; i - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.gpac.${PRODUCT_NAME:identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Osmo4 - CFBundlePackageType - APPL - CFBundleShortVersionString - 9.9.9 - CFBundleSignature - gpac - CFBundleVersion - 9999 - - diff --git a/applications/osmo4_wx/Darwin.Info.plist b/applications/osmo4_wx/Darwin.Info.plist deleted file mode 100644 index 710c02d..0000000 --- a/applications/osmo4_wx/Darwin.Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - Osmo4 - CFBundleGetInfoString - Osmo4 0.4.2 - CFBundleIconFile - Osmo - CFBundleIdentifier - org.gpac.Osmo4 - CFBundleInfoDictionaryVersion - 0.4.2 - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.4.2 - CFBundleSignature - Omo4 - CFBundleVersion - 0.4.2 - NSHumanReadableCopyright - Copyright (c) 2003-2005 gpac - NSMainNibFile - NSMainNibFile - NSPrincipalClass - NSApplication - - diff --git a/applications/osmo4_wx/Darwin.InfoPlist.strings b/applications/osmo4_wx/Darwin.InfoPlist.strings deleted file mode 100644 index 2efc670b7db95be4b0ebd929b71de20bda6a0430..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 456 zcmZ{g$qK?i5Jcls zij2nEX(?A*t#y?zkJ_1-=s;zsm}rOr{}H!<+|oYPA9SR;L48S86__Qyp8D$QgxW*r zYXUza8g)2jO;Ja1n&j;qy`vS~1p55Pi9;p9Rje>$*|=$N>;l#R!ZCB6NBFw=pWHzG z(5t-I!_}TypB_RyKBupvvDG3A>ACFEdOMlO(U2`fRAbHX;j#}`i*zS>tk-t(I)$%1 E0HUT#W&i*H diff --git a/applications/osmo4_wx/Darwin.Osmo.icns b/applications/osmo4_wx/Darwin.Osmo.icns deleted file mode 100644 index a598061aa6d15577ad67469469bec642644b3eca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38570 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 diff --git a/applications/osmo4_wx/Makefile b/applications/osmo4_wx/Makefile deleted file mode 100644 index e15bdac..0000000 --- a/applications/osmo4_wx/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -include ../../config.mak - -vpath %.cpp $(SRC_PATH)/applications/osmo4_wx - -CFLAGS= $(CPPFLAGS) -I"$(SRC_PATH)/include" - -ifeq ($(DEBUGBUILD), yes) -CFLAGS+=-g -LDFLAGS+=-g -endif - -ifeq ($(GPROFBUILD), yes) -CFLAGS+=-pg -LDFLAGS+=-pg -endif - -ifeq ($(GPACREADONLY), yes) -CFLAGS+=-DGPAC_READ_ONLY -endif - -#common obj -OBJS= wxOsmo4.o wxGPACControl.o fileprops.o Playlist.o menubtn.o - -ifeq ($(CONFIG_WIN32),yes) -EXE=.exe -PROG=Osmo4$(EXE) -else -EXT= -PROG=Osmo4 -endif - -#3 - spidermonkey support -ifeq ($(CONFIG_JS),no) -else -SCENEGRAPH_CFLAGS+=$(JS_FLAGS) -ifeq ($(CONFIG_JS),local) -NEED_LOCAL_LIB="yes" -endif -LINKFLAGS+=$(JS_LIBS) -endif - - -SRCS := $(OBJS:.o=.cpp) - -all: $(PROG) - -Osmo4$(EXE): $(OBJS) - $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(WX_LFLAGS) $(LINKFLAGS) - -%.o: %.cpp - $(CXX) $(CFLAGS) $(WX_CFLAGS) -c -o $@ $< - -clean: - rm -f $(OBJS) ../../bin/gcc/$(PROG) - -install: -ifeq ($(CONFIG_DARWIN),yes) - mkdir -p $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/MacOS - mkdir -p $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/Resources/English.lproj - cp ./Darwin.Info.plist \ - $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/Info.plist - cp ./Darwin.InfoPlist.strings \ - $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/Resources/English.lproj/InfoPlist.strings - cp ./Darwin.Osmo.icns \ - $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/Resources/Osmo.icns - install -m 755 $(INSTFLAGS) ../../bin/gcc/Osmo4 \ - $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/MacOS - echo -n 'APPLOsm4' > $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/PkgInfo -else - rm -f wxOsmo4.o - mkdir -p $(DESTDIR)$(prefix)/bin - install -m 755 $(INSTFLAGS) ../../bin/gcc/Osmo4 "$(DESTDIR)$(prefix)/bin" -endif - -uninstall: - rm -rf $(DESTDIR)$(prefix)/bin/Osmo4 - -dep: - -depend: - rm -f .depend - $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend - -distclean: clean - rm -f Makefile.bak .depend - - - -# include dependency files if they exist -# -ifneq ($(wildcard .depend),) -include .depend -endif - diff --git a/applications/osmo4_wx/Playlist.cpp b/applications/osmo4_wx/Playlist.cpp deleted file mode 100644 index 7ed47a6..0000000 --- a/applications/osmo4_wx/Playlist.cpp +++ /dev/null @@ -1,826 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Osmo4 wxWidgets GUI - * - * GPAC is gf_free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#include "wxOsmo4.h" -#include "Playlist.h" - - -#include "playlist.xpm" - -PLEntry::PLEntry(wxString url) -{ - m_url = gf_strdup(url.mb_str(wxConvUTF8)); - Bool is_remote = 0;; - wxCharBuffer the_url = (const char *) url.mb_str(wxConvUTF8); - const char *_url = strstr(the_url, "://"); - if (_url) {_url += 3; is_remote = 1; } - else _url = (const char *) the_url; - - char *str = (char*)strrchr(_url, '\\'); - if (!str) str = (char*)strrchr(_url, '/'); - if (str && strlen(str+1)) { - m_disp_name = gf_strdup(str+1); - str = strrchr(m_disp_name, '.'); - if (str) str[0] = 0; - } else { - m_disp_name = gf_strdup(_url); - if (!is_remote) { - str = strrchr(m_disp_name, '.'); - if (str) str[0] = 0; - } - } - m_duration = 0; - m_bIsDead = 0; - m_bIsPlaying = 0; - m_bIsSelected = 0; -} - -PLEntry::~PLEntry() -{ - if (m_url) gf_free(m_url); - if (m_disp_name) gf_free(m_disp_name); - -} - -wxPlaylist::wxPlaylist(wxWindow *parent) - : wxFrame(parent, -1, wxString(_T("Osmo4 Playlist")), wxDefaultPosition, wxDefaultSize, - wxCLOSE_BOX | wxSYSTEM_MENU | wxCAPTION | wxRESIZE_BORDER) -{ - - m_pApp = (wxOsmo4Frame *)parent; - - m_pOpen = new wxBitmap(pl_open); - m_pSave = new wxBitmap(pl_save); - m_pAdd = new wxBitmap(pl_add); - m_pRem = new wxBitmap(pl_rem); - m_pUp = new wxBitmap(pl_up); - m_pDown = new wxBitmap(pl_down); - m_pSort = new wxBitmap(pl_sort); - - m_pToolBar = CreateToolBar(wxTB_HORIZONTAL); - m_pAddBut = new wxMenuButton(m_pToolBar, ID_PL_ADD_FILE, *m_pAdd); - wxMenu *menu = new wxMenu(); - menu->Append(ID_PL_ADD_URL, wxT("&Url")); - menu->Append(ID_PL_ADD_DIR, wxT("&Directory")); - menu->Append(ID_PL_ADD_DIR_REC, wxT("&Directory and subfolders")); - m_pAddBut->AssignMenu(menu); - m_pAddBut->SetToolTip(wxString(wxT("Add Files"))); - - m_pRemBut = new wxMenuButton(m_pToolBar, ID_PL_REM_FILE, *m_pRem); - menu = new wxMenu(); - menu->Append(ID_PL_REM_ALL, wxT("&Clear")); - menu->Append(ID_PL_REM_DEAD, wxT("&Remove dead entries")); - m_pRemBut->AssignMenu(menu); - m_pRemBut->SetToolTip(wxString(wxT("Remove Selected Files"))); - - m_pSortBut = new wxMenuButton(m_pToolBar, ID_PL_SORT_FILE, *m_pSort); - menu = new wxMenu(); - menu->Append(ID_PL_SORT_TITLE, wxT("&Sort by Title")); - menu->Append(ID_PL_SORT_FILE, wxT("&Sort by file name")); - menu->Append(ID_PL_SORT_DUR, wxT("&Sort by Duration")); - menu->AppendSeparator(); - menu->Append(ID_PL_REVERSE, wxT("&Reverse")); - menu->Append(ID_PL_RANDOMIZE, wxT("&Randomize")); - m_pSortBut->AssignMenu(menu); - m_pSortBut->SetToolTip(wxString(wxT("Sort Playlist by filename"))); - - m_pToolBar->AddTool(ID_PL_OPEN, wxT(""), *m_pOpen, wxT("Open Playlist")); - m_pToolBar->AddTool(ID_PL_SAVE, wxT(""), *m_pSave, wxT("Save Playlist")); - m_pToolBar->AddSeparator(); - m_pToolBar->AddControl(m_pAddBut); - m_pToolBar->AddControl(m_pRemBut); - m_pToolBar->AddSeparator(); - m_pToolBar->AddTool(ID_PL_UP, wxT(""), *m_pUp, wxT("Moves Selected Files Up")); - m_pToolBar->AddTool(ID_PL_DOWN, wxT(""), *m_pDown, wxT("Moves Selected Files Down")); - m_pToolBar->AddSeparator(); - m_pToolBar->AddControl(m_pSortBut); - m_pToolBar->Realize(); - - m_FileList = new wxListCtrl(this, ID_FILE_LIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT); - - m_FileList->InsertColumn(0, wxT(""), wxLIST_FORMAT_LEFT, 1); - m_FileList->InsertColumn(1, wxT("Title"), wxLIST_FORMAT_LEFT, 1); - m_FileList->InsertColumn(2, wxT("Duration"), wxLIST_FORMAT_LEFT, 1); - - m_entries = gf_list_new(); - m_cur_entry = -1; - m_all_dead_entries = -1; - - SetSize(220, 380); - Centre(); -} - -wxPlaylist::~wxPlaylist() -{ - Clear(); - gf_list_del(m_entries); - delete m_pAddBut; - delete m_pRemBut; - delete m_pSortBut; - delete m_pOpen; - delete m_pSave; - delete m_pAdd; - delete m_pRem; - delete m_pUp; - delete m_pDown; - delete m_pSort; -} - - -BEGIN_EVENT_TABLE(wxPlaylist, wxWindow) - EVT_CLOSE(wxPlaylist::OnClose) - EVT_SIZE(wxPlaylist::OnSize) - EVT_TOOL(ID_PL_ADD_FILE, wxPlaylist::OnAddFile) - EVT_TOOL(ID_PL_ADD_URL, wxPlaylist::OnAddURL) - EVT_TOOL(ID_PL_ADD_DIR, wxPlaylist::OnAddDir) - EVT_TOOL(ID_PL_ADD_DIR_REC, wxPlaylist::OnAddDirRec) - EVT_TOOL(ID_PL_REM_FILE, wxPlaylist::OnRemFile) - EVT_TOOL(ID_PL_REM_ALL, wxPlaylist::OnRemAll) - EVT_TOOL(ID_PL_REM_DEAD, wxPlaylist::OnRemDead) - EVT_TOOL(ID_PL_UP, wxPlaylist::OnSelUp) - EVT_TOOL(ID_PL_DOWN, wxPlaylist::OnSelDown) - EVT_TOOL(ID_PL_SAVE, wxPlaylist::OnSave) - EVT_TOOL(ID_PL_OPEN, wxPlaylist::OnOpen) - EVT_MENU(ID_PL_PLAY, wxPlaylist::OnPlay) - EVT_MENU(ID_PL_RANDOMIZE, wxPlaylist::OnRandomize) - EVT_MENU(ID_PL_REVERSE, wxPlaylist::OnReverseList) - EVT_MENU(ID_PL_SEL_REV, wxPlaylist::OnReverseSelection) - EVT_MENU(ID_PL_SORT_TITLE, wxPlaylist::OnSortTitle) - EVT_MENU(ID_PL_SORT_FILE, wxPlaylist::OnSortFile) - EVT_MENU(ID_PL_SORT_DUR, wxPlaylist::OnSortDuration) - EVT_LIST_ITEM_ACTIVATED(ID_FILE_LIST, wxPlaylist::OnItemActivate) - EVT_LIST_ITEM_RIGHT_CLICK(ID_FILE_LIST, wxPlaylist::OnRightClick) -END_EVENT_TABLE() - -void wxPlaylist::OnClose(wxCloseEvent &event) -{ - if (event.CanVeto()) { - event.Veto(); - Hide(); - } -} - -void wxPlaylist::OnSize(wxSizeEvent &event) -{ - wxSize s = event.GetSize(); - m_FileList->SetSize(0, 0, s.GetWidth()-2, s.GetHeight()); - m_FileList->SetColumnWidth(0, 30); - m_FileList->SetColumnWidth(2, 60); - m_FileList->SetColumnWidth(1, s.GetWidth()-96); -} - -void wxPlaylist::Clear() -{ - m_FileList->DeleteAllItems(); - while (gf_list_count(m_entries)) { - PLEntry *ple = (PLEntry *) gf_list_get(m_entries, 0); - gf_list_rem(m_entries, 0); - delete ple; - } - m_cur_entry = -1; -} - -void wxPlaylist::ClearButPlaying() -{ - PLEntry *p = NULL; - if (m_cur_entry >= 0) { - p = (PLEntry *) gf_list_get(m_entries, m_cur_entry); - gf_list_rem(m_entries, m_cur_entry); - } - Clear(); - if (p) { - gf_list_add(m_entries, p); - m_cur_entry = 0; - } - RefreshList(); -} - -void wxPlaylist::UpdateEntry(u32 idx) -{ - char szText[20]; - - PLEntry *ple = (PLEntry *) gf_list_get(m_entries, idx); - if (idx+1<10) sprintf(szText, "00%d", idx+1); - else if (idx+1<100) sprintf(szText, "0%d", idx+1); - else sprintf(szText, "%d", idx+1); - m_FileList->SetItem(idx, 0, wxString(szText, wxConvUTF8)); - - wxString str; - if (ple->m_bIsDead) str = wxT("!! ") + wxString(ple->m_disp_name, wxConvUTF8) + wxT(" (DEAD)!!)"); - else if (ple->m_bIsPlaying) str = wxT(">> ") + wxString(ple->m_disp_name, wxConvUTF8) + wxT(" >>"); - else str = wxString(ple->m_disp_name, wxConvUTF8); - m_FileList->SetItem(idx, 1, str); - - if (ple->m_duration) { - u32 h = (u32) (ple->m_duration / 3600); - u32 m = (u32) (ple->m_duration / 60) - h*60; - u32 s = (u32) (ple->m_duration) - h*3600 - m*60; - m_FileList->SetItem(idx, 2, wxString::Format(wxT("%02d:%02d:%02d"), h, m, s) ); - } else { - m_FileList->SetItem(idx, 2, wxT("Unknown")); - } -} - -void wxPlaylist::RefreshList() -{ - u32 i, top_idx; - char szPath[GF_MAX_PATH]; - Bool first_sel; - - top_idx = m_FileList->GetTopItem(); - m_FileList->DeleteAllItems(); - - first_sel = 0; - for (i=0; iInsertItem(i, wxT("")); - /*cast for 64-bit compilation*/ - m_FileList->SetItemData(i, (unsigned long) ple); - UpdateEntry(i); - - if (ple->m_bIsPlaying) m_cur_entry = i; - - if (ple->m_bIsSelected) { - m_FileList->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED | wxLIST_MASK_STATE); - ple->m_bIsSelected = 0; - /*ensure first item of selection is visible*/ - if (!first_sel) { - first_sel = 1; - top_idx = i; - } - } - } - - if (m_cur_entry >= (s32) gf_list_count(m_entries)-1) m_cur_entry = gf_list_count(m_entries)-1; - else { - s32 last_idx = top_idx + m_FileList->GetCountPerPage(); - m_FileList->EnsureVisible(top_idx); - if (gf_list_count(m_entries)<1+ (u32) last_idx) last_idx = gf_list_count(m_entries)-1; - m_FileList->EnsureVisible(last_idx); - } - - strcpy((char *) szPath, m_pApp->szAppPath); -#ifdef WIN32 - strcat(szPath, "gpac_pl.m3u"); -#else - strcat(szPath, ".gpac_pl.m3u"); -#endif - Save(szPath, 1); -} - -void wxPlaylist::OnAddFile(wxCommandEvent &WXUNUSED(event)) -{ - wxFileDialog dlg(this, wxT("Select file(s)"), wxT(""), wxT(""), m_pApp->GetFileFilter(), wxOPEN | wxCHANGE_DIR | /*wxHIDE_READONLY |*/ wxMULTIPLE); - - if (dlg.ShowModal() == wxID_OK) { - wxArrayString stra; - dlg.GetPaths(stra); - for (u32 i=0; im_pApp->m_term, item_name, 0, 1)) { - PLEntry *ple = new PLEntry(wxString(item_path, wxConvUTF8) ); - gf_list_add(_this->m_entries, ple); - } - return 0; -} - -static Bool pl_enum_dir_dirs(void *cbck, char *item_name, char *item_path) -{ - gf_enum_directory(item_path, 0, pl_enum_dir_item, cbck, NULL); - gf_enum_directory(item_path, 1, pl_enum_dir_dirs, cbck, NULL); - return 0; -} - - -void wxPlaylist::AddDir(Bool do_recurse) -{ - wxDirDialog dlg(this); - dlg.SetPath(wxString(szCacheDir, wxConvUTF8) ); - if (dlg.ShowModal() != wxID_OK) return; - - strcpy(szCacheDir, dlg.GetPath().mb_str(wxConvUTF8)); - gf_enum_directory(szCacheDir, 0, pl_enum_dir_item, this, NULL); - if (do_recurse) gf_enum_directory(szCacheDir, 1, pl_enum_dir_dirs, this, NULL); - m_all_dead_entries = -1; - RefreshList(); -} -void wxPlaylist::OnAddDir(wxCommandEvent &WXUNUSED(event)) -{ - AddDir(0); -} -void wxPlaylist::OnAddDirRec(wxCommandEvent &WXUNUSED(event)) -{ - AddDir(1); -} - -void wxPlaylist::OnAddURL(wxCommandEvent &WXUNUSED(event)) -{ - OpenURLDlg dlg(this, m_pApp->m_user.config); - if (dlg.ShowModal() != wxID_OK) return; - PLEntry *ple = new PLEntry(dlg.m_urlVal); - gf_list_add(m_entries, ple); - m_all_dead_entries = -1; - RefreshList(); -} - -void wxPlaylist::OnRemFile(wxCommandEvent &WXUNUSED(event)) -{ - if (!m_FileList->GetSelectedItemCount()) return; - - long item = -1; - for (;;) { - item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item == -1) break; - PLEntry *ple = (PLEntry *) m_FileList->GetItemData(item); - gf_list_del_item(m_entries, ple); - delete ple; - } - RefreshList(); -} - -void wxPlaylist::OnRemAll(wxCommandEvent &WXUNUSED(event)) -{ - Clear(); - RefreshList(); - m_cur_entry = -1; - m_all_dead_entries = 1; -} - -void wxPlaylist::OnRemDead(wxCommandEvent &WXUNUSED(event)) -{ - for (u32 i=0; im_bIsDead) continue; - gf_list_rem(m_entries, i); - i--; - delete ple; - } - m_all_dead_entries = gf_list_count(m_entries) ? 0 : 1; - RefreshList(); -} - - -void wxPlaylist::OnSelUp(wxCommandEvent &WXUNUSED(event)) -{ - s32 i; - if (!m_FileList->GetSelectedItemCount()) return; - long item = -1; - item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item <= 0) return; - - item = -1; - for (;;) { - item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item == -1) break; - PLEntry *ple = (PLEntry *) m_FileList->GetItemData(item); - i = gf_list_del_item(m_entries, ple); - assert(i>=1); - gf_list_insert(m_entries, ple, i-1); - ple->m_bIsSelected = 1; - } - RefreshList(); -} - -void wxPlaylist::OnSelDown(wxCommandEvent &WXUNUSED(event)) -{ - s32 i; - - if (!m_FileList->GetSelectedItemCount()) return; - long item = -1; - for (;;) { - item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item == -1) break; - } - if ((u32) item + 1 == gf_list_count(m_entries)) return; - - item = -1; - for (;;) { - item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item == -1) break; - PLEntry *ple = (PLEntry *) m_FileList->GetItemData(item); - i = gf_list_del_item(m_entries, ple); - assert(i>=1); - gf_list_insert(m_entries, ple, i+1); - ple->m_bIsSelected = 1; - } - RefreshList(); -} - - - -void wxPlaylist::OnSave(wxCommandEvent & WXUNUSED(event)) -{ - Bool save_m3u; - char szPath[GF_MAX_PATH]; - if (!gf_list_count(m_entries)) return; - - wxFileDialog dlg(this, wxT("Select file(s)"), wxT(""), wxT(""), wxT("M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|"), wxSAVE | wxCHANGE_DIR | wxOVERWRITE_PROMPT); - if (dlg.ShowModal() != wxID_OK) return; - - strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); - strlwr(szPath); - save_m3u = (dlg.GetFilterIndex()==0) ? 1 : 0; - if (save_m3u) { - if (!strstr(szPath, ".m3u")) { - strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); - strcat(szPath, ".m3u"); - } else { - strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); - } - } else { - if (!strstr(szPath, ".pls")) { - strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); - strcat(szPath, ".pls"); - } else { - strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); - } - } - Save(szPath, save_m3u); -} - -void wxPlaylist::Save(char *szPath, Bool save_m3u) -{ - FILE *out = fopen(szPath, "wt"); - if (!save_m3u) - fprintf(out, "[playlist]\nNumberOfEntries=%d\n", gf_list_count(m_entries)); - - for (u32 i=0; im_url); - } else { - fprintf(out, "File%d=%s\n", i+1, ple->m_url); - fprintf(out, "Title%d=%s\n", i+1, ple->m_disp_name); - if (ple->m_duration) fprintf(out, "Length%d=%d\n", i+1, ple->m_duration); - else fprintf(out, "Length%d=-1\n", i+1); - } - } - if (!save_m3u) fprintf(out, "Version=2\n"); - - fprintf(out, "\n"); - fclose(out); -} - -void wxPlaylist::OnOpen(wxCommandEvent & WXUNUSED(event)) -{ - wxFileDialog dlg(this, wxT("Select file(s)"), wxT(""), wxT(""), wxT("M3U & PLS Playlists|*.m3u;*.pls|M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|"), wxOPEN | wxCHANGE_DIR/* | wxHIDE_READONLY*/); - if (dlg.ShowModal() != wxID_OK) return; - - Clear(); - OpenPlaylist(dlg.GetPath()); - m_cur_entry = 0; - Play(); -} - -void wxPlaylist::OpenPlaylist(wxString filename) -{ - FILE *pl; - PLEntry *ple; - Bool load_m3u, go; - char szLine[GF_MAX_PATH]; - pl = fopen(filename.mb_str(wxConvUTF8) , "rt"); - if (!pl) return; - - ple = NULL; - load_m3u = 1; - while (!feof(pl)) { - fgets(szLine, GF_MAX_PATH, pl); - go = 1; - while (go) { - switch (szLine[strlen(szLine)-1]) { - case '\n': - case '\r': - case ' ': - szLine[strlen(szLine)-1] = 0; - break; - default: - go = 0; - break; - } - } - if (!strlen(szLine)) continue; - if (!stricmp(szLine, "[playlist]")) { - load_m3u = 0; - } else if (load_m3u) { - ple = new PLEntry(wxString(szLine, wxConvUTF8) ); - gf_list_add(m_entries, ple); - } else if (!strnicmp(szLine, "file", 4)) { - char *st = strchr(szLine, '='); - if (!st) ple = NULL; - else { - ple = new PLEntry(wxString(st + 1, wxConvUTF8) ); - gf_list_add(m_entries, ple); - } - } else if (ple && !strnicmp(szLine, "Length", 6)) { - char *st = strchr(szLine, '='); - s32 d = atoi(st + 1); - if (d>0) ple->m_duration = d; - } else if (ple && !strnicmp(szLine, "Title", 5)) { - char *st = strchr(szLine, '='); - gf_free(ple->m_disp_name); - ple->m_disp_name = gf_strdup(st + 6); - } - } - fclose(pl); - m_all_dead_entries = -1; - m_cur_entry = -1; - RefreshList(); -} - -void wxPlaylist::OnRightClick(wxListEvent & event) -{ - if (!m_FileList->GetItemCount()) return; - - wxMenu *popup = new wxMenu(); - - if (m_FileList->GetSelectedItemCount()==1) { - popup->Append(ID_PL_PLAY, wxT("Play")); - popup->AppendSeparator(); - } - popup->Append(ID_PL_SEL_REV, wxT("Inverse Selection")); - if (m_FileList->GetSelectedItemCount()) popup->Append(ID_PL_REM_FILE, wxT("Remove File(s)")); - if (m_FileList->GetItemCount()>1) { - popup->AppendSeparator(); - popup->Append(ID_PL_SORT_TITLE, wxT("Sort By Title")); - popup->Append(ID_PL_SORT_FILE, wxT("Sort By File Name")); - popup->Append(ID_PL_SORT_DUR, wxT("Sort By Duration")); - popup->AppendSeparator(); - popup->Append(ID_PL_REVERSE, wxT("Reverse List")); - popup->Append(ID_PL_RANDOMIZE, wxT("Randomize")); - } - - PopupMenu(popup, event.GetPoint()); - delete popup; -} - -void wxPlaylist::OnReverseSelection(wxCommandEvent &WXUNUSED(event) ) -{ - u32 i; - long item = -1; - for (;;) { - item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item == -1) break; - PLEntry *ple = (PLEntry *) m_FileList->GetItemData(item); - ple->m_bIsSelected = 1; - } - for (i=0; im_bIsSelected = !ple->m_bIsSelected; - } - RefreshList(); -} - -void wxPlaylist::OnReverseList(wxCommandEvent &WXUNUSED(event) ) -{ - u32 count = gf_list_count(m_entries); - u32 hcount = count / 2; - count--; - for (u32 i=0; i1) { - u32 pos = gf_rand() % (gf_list_count(m_entries)-1); - PLEntry *ple = (PLEntry *)gf_list_get(m_entries, pos); - gf_list_rem(m_entries, pos); - gf_list_add(new_entries, ple); - } - PLEntry *ple = (PLEntry *)gf_list_get(m_entries, 0); - gf_list_rem(m_entries, 0); - gf_list_add(new_entries, ple); - - gf_list_del(m_entries); - m_entries = new_entries; - m_cur_entry = -1; - RefreshList(); -} - -void wxPlaylist::Sort(u32 type) -{ - u32 i, j, smallest; - - for (i=0; im_url, ple2->m_url); - break; - case 1: - test = stricmp(ple1->m_disp_name, ple2->m_disp_name); - break; - case 2: - test = ple1->m_duration - ple2->m_duration; - break; - } - if (test<0) smallest = j; - } - PLEntry *ple = (PLEntry *)gf_list_get(m_entries, smallest); - gf_list_rem(m_entries, smallest); - gf_list_insert(m_entries, ple, i); - } - m_cur_entry = -1; - RefreshList(); -} - -void wxPlaylist::OnSortFile(wxCommandEvent &WXUNUSED(event) ) { Sort(0); } -void wxPlaylist::OnSortTitle(wxCommandEvent &WXUNUSED(event) ) { Sort(1); } -void wxPlaylist::OnSortDuration(wxCommandEvent &WXUNUSED(event) ) { Sort(2); } - -void wxPlaylist::RefreshCurrent() -{ - PLEntry *ple; - if (m_cur_entry<0) return; - ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); - if (ple && ple->m_bIsPlaying) { - ple->m_bIsPlaying = 0; - UpdateEntry(m_cur_entry); - } -} - -Bool wxPlaylist::HasValidEntries() -{ - u32 nb_dead = 0; - if (m_all_dead_entries==-1) { - for (u32 i=0; im_bIsPlaying = 0; - if (ple->m_bIsDead) nb_dead ++; - } - m_all_dead_entries = (nb_dead==gf_list_count(m_entries)) ? 1 : 0; - } - return !m_all_dead_entries; -} - -void wxPlaylist::Play() -{ - PLEntry *ple; - - if (!HasValidEntries()) return; - - RefreshCurrent(); - - if (m_cur_entry >= (s32)gf_list_count(m_entries)) { - if (!m_pApp->m_loop) return; - m_cur_entry = 0; - } - - ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); - if (!ple || ple->m_bIsDead) { - m_cur_entry++; - Play(); - } else { - char szPLE[20]; - ple->m_bIsPlaying = 1; - UpdateEntry(m_cur_entry); - sprintf(szPLE, "%d", m_cur_entry); - gf_cfg_set_key(m_pApp->m_user.config, "General", "PLEntry", szPLE); - m_pApp->DoConnect(); - } -} - -void wxPlaylist::OnItemActivate(wxListEvent &WXUNUSED(event) ) -{ - long item = m_FileList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item==-1) return; - RefreshCurrent(); - m_cur_entry = item; - Play(); -} - - -void wxPlaylist::OnPlay(wxCommandEvent &WXUNUSED(event)) -{ - long item = m_FileList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item==-1) return; - - RefreshCurrent(); - m_cur_entry = item; - Play(); -} - -void wxPlaylist::Truncate() -{ - if (m_cur_entry<0) return; - while ((u32) m_cur_entry+1 < gf_list_count(m_entries)) { - PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry+1); - gf_list_rem(m_entries, m_cur_entry+1); - delete ple; - } - RefreshList(); -} - -void wxPlaylist::QueueURL(wxString filename) -{ - char *ext = (char*)strrchr(filename.mb_str(wxConvUTF8), '.'); - if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls")) ) { - OpenPlaylist(filename); - } else { - PLEntry *ple = new PLEntry(filename); - gf_list_add(m_entries, ple); - } -} - -void wxPlaylist::PlayNext() -{ - RefreshCurrent(); - if (1+m_cur_entry < (s32)gf_list_count(m_entries)) { - m_cur_entry++; - Play(); - } -} - -void wxPlaylist::PlayPrev() -{ - RefreshCurrent(); - if (m_cur_entry>0) { - m_cur_entry--; - Play(); - } -} - -void wxPlaylist::SetDead() -{ - PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); - if (ple) { - ple->m_bIsDead = 1; - UpdateEntry(m_cur_entry); - if (ple->m_bIsPlaying) PlayNext(); - m_all_dead_entries = -1; - } -} -void wxPlaylist::SetDuration(u32 duration) -{ - PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); - if (ple) { - ple->m_duration = duration; - UpdateEntry(m_cur_entry); - } -} - -wxString wxPlaylist::GetDisplayName() -{ - if (m_cur_entry>=0) { - PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); - if (ple) return wxString(wxString(ple->m_disp_name, wxConvUTF8) ); - } - return wxT(""); -} - -wxString wxPlaylist::GetURL() -{ - PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); - if (ple) return wxString(ple->m_url, wxConvUTF8); - return wxT(""); -} - diff --git a/applications/osmo4_wx/Playlist.h b/applications/osmo4_wx/Playlist.h deleted file mode 100644 index 0ebb230..0000000 --- a/applications/osmo4_wx/Playlist.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Osmo4 wxWidgets GUI - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#ifndef _PLAYLIST_H -#define _PLAYLIST_H - -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include "menubtn.h" - -enum -{ - ID_FILE_LIST = 1000, -}; - -class wxOsmo4Frame; - -class PLEntry -{ -public: - PLEntry(wxString url); - ~PLEntry(); - - char *m_url; - char *m_disp_name; - u32 m_duration; - - Bool m_bIsSelected; - Bool m_bIsDead; - Bool m_bIsPlaying; -}; - - -class wxPlaylist : public wxFrame -{ -public: - wxPlaylist(wxWindow *parent); - virtual ~wxPlaylist(); - - void Clear(); - void ClearButPlaying(); - void RefreshList(); - - void Truncate(); - void QueueURL(wxString filename); - void Play(); - void PlayNext(); - void PlayPrev(); - void SetDead(); - void SetDuration(u32 duration); - Bool HasValidEntries(); - void OpenPlaylist(wxString fileName); - - /*for current entry played*/ - wxString GetDisplayName(); - wxString GetURL(); - - s32 m_cur_entry; - GF_List *m_entries; - - wxOsmo4Frame *m_pApp; - -private: - DECLARE_EVENT_TABLE() - - void OnClose(wxCloseEvent &event); - void OnSize(wxSizeEvent &event); - void OnAddFile(wxCommandEvent &event); - void OnAddURL(wxCommandEvent &event); - void OnAddDir(wxCommandEvent &event); - void OnAddDirRec(wxCommandEvent &event); - void OnRemFile(wxCommandEvent &event); - void OnRemAll(wxCommandEvent &event); - void OnRemDead(wxCommandEvent &event); - void OnSelUp(wxCommandEvent &event); - void OnSelDown(wxCommandEvent &event); - void OnSave(wxCommandEvent &event); - void OnOpen(wxCommandEvent &event); - void OnRightClick(wxListEvent & event); - void OnReverseSelection(wxCommandEvent &event); - void OnReverseList(wxCommandEvent &event); - void OnRandomize(wxCommandEvent &event); - void OnSortFile(wxCommandEvent &event); - void OnSortTitle(wxCommandEvent &event); - void OnSortDuration(wxCommandEvent &event); - void OnItemActivate(wxListEvent &event); - void OnPlay(wxCommandEvent &event); - - - void Sort(u32 type); - void UpdateEntry(u32 idx); - void RefreshCurrent(); - void Save(char *szPath, Bool save_m3u); - - wxBitmap *m_pOpen, *m_pSave, *m_pAdd, *m_pRem, *m_pUp, *m_pDown, *m_pSort; - wxMenuButton *m_pAddBut, *m_pRemBut, *m_pSortBut; - wxToolBar *m_pToolBar; - wxListCtrl *m_FileList; - char szCacheDir[GF_MAX_PATH]; - s32 m_all_dead_entries; - - void AddDir(Bool do_recurse); -}; - - - -#endif - diff --git a/applications/osmo4_wx/fileprops.cpp b/applications/osmo4_wx/fileprops.cpp deleted file mode 100644 index 4697d55..0000000 --- a/applications/osmo4_wx/fileprops.cpp +++ /dev/null @@ -1,608 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Osmo4 wxWidgets GUI - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#include "fileprops.h" -#include "wxOsmo4.h" -#include "Playlist.h" -#include -#include -#include -#include -/*ISO 639 languages*/ -#include - - -wxFileProps::wxFileProps(wxWindow *parent) - : wxDialog(parent, -1, wxString(_T("File Properties"))) -{ - - m_pApp = (wxOsmo4Frame *)parent; - SetSize(540, 260); - assert(m_pApp->m_pPlayList); - - m_pTreeView = new wxTreeCtrl(this, ID_TREE_VIEW, wxPoint(4, 2), wxSize(200, 180), wxTR_DEFAULT_STYLE | wxSUNKEN_BORDER); - - new wxStaticText(this, 0, _T("Information"), wxPoint(210, 2), wxSize(60, 20)); - m_pViewSel = new wxComboBox(this, ID_VIEW_SEL, _T(""), wxPoint(280, 2), wxSize(120, 24), 0, NULL, wxCB_READONLY); - m_pViewSel->Append(wxT("General")); - m_pViewSel->Append(wxT("Streams")); - m_pViewSel->Append(wxT("Playback")); - m_pViewSel->Append(wxT("Network")); - m_pViewSel->SetSelection(0); - - m_pViewInfo = new wxTextCtrl(this, -1, wxT(""), wxPoint(210, 30), wxSize(320, 200), wxTE_MULTILINE | wxTE_READONLY | wxHSCROLL | wxSUNKEN_BORDER); - -#ifdef WIN32 - m_pViewInfo->SetBackgroundColour(wxColour(wxT("LIGHT GREY"))); -#endif - - m_pViewWI = new wxButton(this, ID_VIEW_WI, wxT("View World Info"), wxPoint(4, 174), wxSize(200, 40)); - m_pViewSG = new wxButton(this, ID_VIEW_SG, wxT("View Scene Graph"), wxPoint(4, 220), wxSize(200, 40)); - - - wxString str = m_pApp->m_pPlayList->GetDisplayName(); - str += wxT(" Properties"); - SetTitle(str); - - m_pTimer = new wxTimer(); - m_pTimer->SetOwner(this, ID_OD_TIMER); - m_pTimer->Start(500, 0); - RewriteODTree(); - -} - -wxFileProps::~wxFileProps() -{ - m_pTimer->Stop(); - delete m_pTimer; -} - - -BEGIN_EVENT_TABLE(wxFileProps, wxDialog) - EVT_TREE_ITEM_ACTIVATED(ID_TREE_VIEW, wxFileProps::OnSetSelection) - EVT_TREE_SEL_CHANGED(ID_TREE_VIEW, wxFileProps::OnSetSelection) - EVT_TREE_ITEM_EXPANDED(ID_TREE_VIEW, wxFileProps::OnSetSelection) - EVT_TREE_ITEM_COLLAPSED(ID_TREE_VIEW, wxFileProps::OnSetSelection) - EVT_TIMER(ID_OD_TIMER, wxFileProps::OnTimer) - EVT_BUTTON(ID_VIEW_SG, wxFileProps::OnViewSG) - EVT_BUTTON(ID_VIEW_WI, wxFileProps::OnViewWorld) - EVT_COMBOBOX(ID_VIEW_SEL, wxFileProps::OnSelectInfo) -END_EVENT_TABLE() - -void wxFileProps::RewriteODTree() -{ - GF_ObjectManager *root_odm = gf_term_get_root_object(m_pApp->m_term); - if (!root_odm) return; - - m_pTreeView->DeleteAllItems(); - ODTreeData *root = new ODTreeData(root_odm); - m_pTreeView->AddRoot(wxT("Root OD"), -1, -1, root); - wxTreeItemId rootId = m_pTreeView->GetRootItem(); - - WriteInlineTree(root); - SetInfo(root_odm); -} - -void wxFileProps::WriteInlineTree(ODTreeData *root) -{ - /*browse all ODs*/ - u32 count = gf_term_get_object_count(m_pApp->m_term, root->m_pODMan); - - for (u32 i=0; im_term, root->m_pODMan, i); - if (!odm) return; - ODTreeData *odd = new ODTreeData(odm); - m_pTreeView->AppendItem(root->GetId(), wxT("Object Descriptor"), -1, -1, odd); - - /*if inline propagate*/ - switch (gf_term_object_subscene_type(m_pApp->m_term, odm)) { - case 1: - m_pTreeView->SetItemText(odd->GetId(), wxT("Root Scene")); - WriteInlineTree(odd); - break; - case 2: - m_pTreeView->SetItemText(odd->GetId(), wxT("Inline Scene")); - WriteInlineTree(odd); - break; - case 3: - m_pTreeView->SetItemText(odd->GetId(), wxT("Extern Proto Lib")); - break; - default: - break; - } - } -} - -void wxFileProps::OnSetSelection(wxTreeEvent& event) -{ - ODTreeData *odd = (ODTreeData *) m_pTreeView->GetItemData(event.GetItem()); - SetInfo(odd->m_pODMan); -} - -void wxFileProps::SetInfo(GF_ObjectManager *odm) -{ - m_current_odm = odm; - - switch (m_pViewSel->GetSelection()) { - case 3: SetNetworkInfo(); break; - case 2: SetDecoderInfo(); break; - case 1: SetStreamsInfo(); break; - default: SetGeneralInfo(); break; - } -} - -void wxFileProps::OnTimer(wxTimerEvent& WXUNUSED(event)) -{ - switch (m_pViewSel->GetSelection()) { - case 2: SetDecoderInfo(); break; - } -} -void wxFileProps::OnSelectInfo(wxCommandEvent & WXUNUSED(event) ) -{ - SetInfo(m_current_odm); -} - -void wxFileProps::SetGeneralInfo() -{ - wxString info; - GF_MediaInfo odi; - u32 h, m, s; - u32 i, j; - - info = wxT(""); - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); - - if (!m_current_odm || gf_term_get_object_info(m_pApp->m_term, m_current_odm, &odi) != GF_OK) return; - - if (odi.has_profiles) info += wxT("Initial "); - info += wxString::Format(wxT("Object Descriptor ID %d\n"), odi.od->objectDescriptorID); - if (odi.duration) { - h = (u32) (odi.duration / 3600); - m = (u32) (odi.duration / 60) - h*60; - s = (u32) (odi.duration) - h*3600 - m*60; - info += wxString::Format(wxT("Duration %02d:%02d:%02d\n"), h, m, s); - } else { - info += wxT("Unknown duration\n"); - } - - if (odi.owns_service) { - info += wxT("Service Handler: ") + wxString(odi.service_handler, wxConvUTF8) + wxT("\n"); - info += wxT("Service URL: ") + wxString(odi.service_url, wxConvUTF8) + wxT("\n"); - } - - if (odi.od->URLString) { - info += wxT("Remote OD - URL: ") + wxString(odi.od->URLString, wxConvUTF8) + wxT("\n"); - } - - if (odi.codec_name) { - switch (odi.od_type) { - case GF_STREAM_VISUAL: - info += wxString::Format(wxT("Video Object: Width %d - Height %d\n"), odi.width, odi.height); - info += wxT("Media Codec ") + wxString(odi.codec_name, wxConvUTF8) + wxT("\n"); - break; - case GF_STREAM_AUDIO: - info += wxString::Format(wxT("Audio Object: Sample Rate %d - %d channels\n"), odi.sample_rate, odi.num_channels); - info += wxT("Media Codec ") + wxString(odi.codec_name, wxConvUTF8) + wxT("\n"); - break; - case GF_STREAM_PRIVATE_SCENE: - case GF_STREAM_SCENE: - if (odi.width && odi.height) { - info += wxString::Format(wxT("Scene Description: Width %d - Height %d\n"), odi.width, odi.height); - } else { - info += wxT("Scene Description: No size specified\n"); - } - info += wxT("Scene Codec ") + wxString(odi.codec_name, wxConvUTF8) + wxT("\n"); - break; - case GF_STREAM_TEXT: - if (odi.width && odi.height) { - info += wxString::Format(wxT("Text Object: Width %d - Height %d\n"), odi.width, odi.height); - } else { - info += wxString::Format(wxT("Text Object: No size specified\n")); - } - info += wxT("Text Codec ") + wxString(odi.codec_name, wxConvUTF8) + wxT("\n"); - break; - } - } - if (odi.protection==2) info += wxT("Encrypted Media NOT UNLOCKED"); - else if (odi.protection==1) info += wxT("Encrypted Media"); - - if (!gf_list_count(odi.od->OCIDescriptors)) { - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); - return; - } - - info += wxT("\nObject Content Information:\n"); - - /*check OCI (not everything interests us) - FIXME: support for unicode*/ - for (i=0; iOCIDescriptors); i++) { - GF_Descriptor *desc = (GF_Descriptor *) gf_list_get(odi.od->OCIDescriptors, i); - switch (desc->tag) { - case GF_ODF_SEGMENT_TAG: - { - GF_Segment *sd = (GF_Segment *) desc; - info += wxT("\nSegment Descriptor:\nName: ") + wxString((char *) sd->SegmentName, wxConvUTF8); - info += wxString::Format(wxT(" - start time %g sec - duration %g sec\n"), sd->startTime, sd->Duration); - } - break; - case GF_ODF_CC_NAME_TAG: - { - GF_CC_Name *ccn = (GF_CC_Name *)desc; - info += wxT("\nContent Creators:\n"); - for (j=0; jContentCreators); j++) { - GF_ContentCreatorInfo *ci = (GF_ContentCreatorInfo *) gf_list_get(ccn->ContentCreators, j); - if (!ci->isUTF8) continue; - info += wxT("\t") + wxString(ci->contentCreatorName, wxConvUTF8) + wxT("\n"); - } - } - break; - - case GF_ODF_SHORT_TEXT_TAG: - { - GF_ShortTextual *std = (GF_ShortTextual *)desc; - info += wxT("\n") + wxString(std->eventName, wxConvUTF8) + wxT(": ") + wxString(std->eventText, wxConvUTF8) + wxT("\n"); - } - break; - /*todo*/ - case GF_ODF_CC_DATE_TAG: - break; - default: - break; - } - - } - - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); -} - -void wxFileProps::SetStreamsInfo() -{ - u32 i, count; - wxString info; - GF_MediaInfo odi; - char code[5]; - - info = wxT(""); - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); - - if (!m_current_odm || gf_term_get_object_info(m_pApp->m_term, m_current_odm, &odi) != GF_OK) return; - - if (odi.has_profiles) { - info += wxString::Format(wxT("\tOD Profile@Level %d\n"), odi.OD_pl); - info += wxString::Format(wxT("\tScene Profile@Level %d\n"), odi.scene_pl); - info += wxString::Format(wxT("\tGraphics Profile@Level %d\n"), odi.graphics_pl); - info += wxString::Format(wxT("\tAudio Profile@Level %d\n"), odi.audio_pl); - info += wxString::Format(wxT("\tVisual Profile@Level %d\n"), odi.scene_pl); - if (odi.inline_pl) info += wxT("\tInline Content use same profiles\n"); - info += wxT("\n"); - } - - count = gf_list_count(odi.od->ESDescriptors); - - for (i=0; iESDescriptors, i); - - info += wxString::Format(wxT("Stream ID %d - Clock ID %d\n"), esd->ESID, esd->OCRESID); - if (esd->dependsOnESID) { - info += wxString::Format(wxT("\tDepends on Stream ID %d for decoding\n"), esd->dependsOnESID); - } - switch (esd->decoderConfig->streamType) { - case GF_STREAM_OD: - info += wxString::Format(wxT("\tOD Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_OCR: - info += wxT("\tObject Clock Reference Stream\n"); - break; - case GF_STREAM_SCENE: - info += wxString::Format(wxT("\tScene Description Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_PRIVATE_SCENE: - info += wxString::Format(wxT("\tGPAC Private Scene Description Stream\n")); - break; - case GF_STREAM_VISUAL: - info += wxT("\tVisual Stream - media type: "); - switch (esd->decoderConfig->objectTypeIndication) { - case GPAC_OTI_VIDEO_MPEG4_PART2: info += wxT("MPEG-4\n"); break; - case GPAC_OTI_VIDEO_MPEG2_SIMPLE: info += wxT("MPEG-2 Simple Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_MAIN: info += wxT("MPEG-2 Main Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_SNR: info += wxT("MPEG-2 SNR Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_SPATIAL: info += wxT("MPEG-2 Spatial Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_HIGH: info += wxT("MPEG-2 High Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG2_422: info += wxT("MPEG-2 422 Profile\n"); break; - case GPAC_OTI_VIDEO_MPEG1: info += wxT("MPEG-1\n"); break; - case GPAC_OTI_IMAGE_JPEG: info += wxT("JPEG\n"); break; - case GPAC_OTI_IMAGE_PNG: info += wxT("PNG\n"); break; - case GPAC_OTI_IMAGE_JPEG_2000: info += wxT("JPEG2000\n"); break; - case 0x80: - memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); - code[4] = 0; - info += wxT("GPAC Intern (") + wxString(code, wxConvUTF8) + wxT(")\n"); - break; - default: - info += wxString::Format(wxT("Private/Unknown Type (0x%x)\n"), esd->decoderConfig->objectTypeIndication); - break; - } - break; - - case GF_STREAM_AUDIO: - info += wxT("\tAudio Stream - media type: "); - switch (esd->decoderConfig->objectTypeIndication) { - case GPAC_OTI_AUDIO_AAC_MPEG4: info += wxT("MPEG-4\n"); break; - case GPAC_OTI_AUDIO_AAC_MPEG2_MP: info += wxT("MPEG-2 AAC Main Profile\n"); break; - case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: info += wxT("MPEG-2 AAC LowComplexity Profile\n"); break; - case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: info += wxT("MPEG-2 AAC Scalable Sampling Rate Profile\n"); break; - case GPAC_OTI_AUDIO_MPEG2_PART3: info += wxT("MPEG-2 Audio\n"); break; - case GPAC_OTI_AUDIO_MPEG1: info += wxT("MPEG-1 Audio\n"); break; - case 0xA0: info += wxT("EVRC Audio\n"); break; - case 0xA1: info += wxT("SMV Audio\n"); break; - case 0xE1: info += wxT("QCELP Audio\n"); break; - case 0x80: - memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); - code[4] = 0; - info += wxT("GPAC Intern (") + wxString(code, wxConvUTF8) + wxT(")\n"); - break; - default: - info += wxString::Format(wxT("Private/Unknown Type (0x%x)\n"), esd->decoderConfig->objectTypeIndication); - break; - } - break; - case GF_STREAM_MPEG7: - info += wxString::Format(wxT("\tMPEG-7 Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_IPMP: - info += wxString::Format(wxT("\tIPMP Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_OCI: - info += wxString::Format(wxT("\tOCI Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_MPEGJ: - info += wxString::Format(wxT("\tMPEGJ Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_INTERACT: - info += wxString::Format(wxT("\tUser Interaction Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); - break; - default: - info += wxT("Private/Unknown\n"); - break; - } - - info += wxString::Format(wxT("\tBuffer Size %d\n\tAverage Bitrate %d bps\n\tMaximum Bitrate %d bps\n"), esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate, esd->decoderConfig->maxBitrate); - if (esd->slConfig->predefined==SLPredef_SkipSL) { - info += wxString::Format(wxT("\tNot using MPEG-4 Synchronization Layer\n")); - } else { - info += wxString::Format(wxT("\tStream Clock Resolution %d\n"), esd->slConfig->timestampResolution); - } - if (esd->URLString) - info += wxT("\tStream Location: ") + wxString(esd->URLString, wxConvUTF8) + wxT("\n"); - - /*check language*/ - if (esd->langDesc) { - u32 i=0; - char lan[4], *szLang; - lan[0] = esd->langDesc->langCode>>16; - lan[1] = (esd->langDesc->langCode>>8)&0xFF; - lan[2] = (esd->langDesc->langCode)&0xFF; - lan[3] = 0; - - if ((lan[0]=='u') && (lan[1]=='n') && (lan[2]=='d')) szLang = (char*) "Undetermined"; - else { - szLang = lan; - while (GF_ISO639_Lang[i]) { - if (GF_ISO639_Lang[i+2][0] && strstr(GF_ISO639_Lang[i+1], lan)) { - szLang = (char*) GF_ISO639_Lang[i]; - break; - } - i+=3; - } - } - info += wxString::Format(wxT("\tStream Language: %s\n"), szLang); - } - - } - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); -} - - -void wxFileProps::SetDecoderInfo() -{ - GF_MediaInfo odi; - wxString info; - u32 h, m, s; - - if (!m_current_odm || gf_term_get_object_info(m_pApp->m_term, m_current_odm, &odi)) { - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); - return; - } - - info = wxT("Status: "); - switch (odi.status) { - case 0: - case 1: - case 2: - h = (u32) (odi.current_time / 3600); - m = (u32) (odi.current_time / 60) - h*60; - s = (u32) (odi.current_time) - h*3600 - m*60; - if (odi.status==0) info += wxT("Stopped"); - else if (odi.status==1) info += wxT("Playing"); - else info += wxT("Paused"); - info += wxString::Format(wxT("\nObject Time: %02d:%02d:%02d\n"), h, m, s); - break; - case 3: - info += wxT("Not Setup\n"); - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); - return; - default: - info += wxT("Setup Failed\n"); - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); - return; - } - /*get clock drift*/ - info += wxString::Format(wxT("Clock drift: %d ms\n"), odi.clock_drift); - /*get buffering*/ - if (odi.buffer>=0) info += wxString::Format(wxT("Buffering Time: %d ms\n"), odi.buffer); - else if (odi.buffer==-1) info += wxT("Not buffering\n"); - else info += wxT("Not Playing\n"); - - /*get DB occupation*/ - if (odi.buffer>=0) info += wxString::Format(wxT("Decoding Buffer: %d Access Units\n"), odi.db_unit_count); - /*get CB occupation*/ - if (odi.cb_max_count) - info += wxString::Format(wxT("Composition Memory: %d/%d Units\n"), odi.cb_unit_count, odi.cb_max_count); - - Float avg_dec_time = 0; - if (odi.nb_dec_frames) { - avg_dec_time = (Float) odi.total_dec_time; - avg_dec_time /= odi.nb_dec_frames; - } - info += wxString::Format(wxT("Average Bitrate %d kbps (%d max)\nAverage Decoding Time %.2f ms (%d max)\nTotal decoded frames %d - %d dropped\n"), - (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time, odi.nb_dec_frames, odi.nb_droped); - - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); -} - -void wxFileProps::SetNetworkInfo() -{ - wxString info; - u32 id; - NetStatCommand com; - GF_MediaInfo odi; - u32 d_enum; - GF_Err e; - - info = wxT(""); - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(wxT("")); - - if (!m_current_odm || gf_term_get_object_info(m_pApp->m_term, m_current_odm, &odi) != GF_OK) return; - - if (odi.owns_service) { - const char *url, *path; - u32 done, total, bps; - info = wxT("Current Downloads in service:\n"); - d_enum = 0; - while (gf_term_get_download_info(m_pApp->m_term, m_current_odm, &d_enum, &url, &path, &done, &total, &bps)) { - info += wxString(url, wxConvUTF8); - if (total) { - info += wxString::Format(wxT(": %d / %d bytes (%.2f %%) - %.2f kBps\n"), done, total, (100.0*done)/total, ((Double)bps)/1024); - } else { - info += wxString::Format(wxT(": %.2f kBps\n"), ((Double)bps)/1024); - } - } - if (!d_enum) info = wxT("No Downloads in service\n"); - info += wxT("\n"); - } - - d_enum = 0; - while (gf_term_get_channel_net_info(m_pApp->m_term, m_current_odm, &d_enum, &id, &com, &e)) { - if (e) continue; - if (!com.bw_down && !com.bw_up) continue; - - info += wxString::Format(wxT("Stream ID %d statistics:\n"), id); - if (com.multiplex_port) { - info += wxString::Format(wxT("\tMultiplex Port %d - multiplex ID %d\n"), com.multiplex_port, com.port); - } else { - info += wxString::Format(wxT("\tPort %d\n"), com.port); - } - info += wxString::Format(wxT("\tPacket Loss Percentage: %.4f\n"), com.pck_loss_percentage); - info += wxString::Format(wxT("\tDown Bandwidth: %.3f bps\n"), ((Float)com.bw_down)/1024); - if (com.bw_up) info += wxString::Format(wxT("\tUp Bandwidth: %d bps\n"), com.bw_up); - if (com.ctrl_port) { - if (com.multiplex_port) { - info += wxString::Format(wxT("\tControl Multiplex Port: %d - Control Multiplex ID %d\n"), com.multiplex_port, com.ctrl_port); - } else { - info += wxString::Format(wxT("\tControl Port: %d\n"), com.ctrl_port); - } - info += wxString::Format(wxT("\tControl Down Bandwidth: %d bps\n"), com.ctrl_bw_down); - info += wxString::Format(wxT("\tControl Up Bandwidth: %d bps\n"), com.ctrl_bw_up); - } - info += wxT("\n"); - } - m_pViewInfo->Clear(); - m_pViewInfo->AppendText(info); -} - - -void wxFileProps::OnViewWorld(wxCommandEvent &WXUNUSED(event)) -{ - wxString wit; - const char *str; - GF_List *descs; - descs = gf_list_new(); - str = gf_term_get_world_info(m_pApp->m_term, m_current_odm, descs); - - if (!str) { - wxMessageDialog(this, wxT("No World Info available"), wxT("Sorry!"), wxOK).ShowModal(); - return; - } - - wit = wxT(""); - for (u32 i=0; gf_list_count(descs); i++) { - const char *d = (const char *) gf_list_get(descs, i); - wit += wxString(d, wxConvUTF8); - wit += wxT("\n"); - } - wxMessageDialog(this, wit, wxString(str, wxConvUTF8), wxOK).ShowModal(); - gf_list_del(descs); -} - -void wxFileProps::OnViewSG(wxCommandEvent &WXUNUSED(event)) -{ - const char *sOpt; - Bool dump_xmt; - wxFileName out_file; - char szOutFile[GF_MAX_PATH]; - wxString fname; - - sOpt = gf_cfg_get_key(m_pApp->m_user.config, "General", "CacheDirectory"); - out_file.AssignDir(wxString(sOpt, wxConvUTF8) ); - - sOpt = gf_cfg_get_key(m_pApp->m_user.config, "General", "ViewXMT"); - out_file.SetFullName(wxT("scene_dump")); - if (sOpt && !stricmp(sOpt, "yes")) { - dump_xmt = 1; - } else { - dump_xmt = 0; - } - strcpy(szOutFile, out_file.GetFullName().mb_str(wxConvUTF8)); - - GF_Err e = gf_term_dump_scene(m_pApp->m_term, szOutFile, NULL, dump_xmt, 0, m_current_odm); - if (e) { - wxMessageDialog dlg(this, wxString(gf_error_to_string(e), wxConvUTF8), wxT("Error while dumping"), wxOK); - dlg.ShowModal(); - } else { - wxString cmd = get_pref_browser(m_pApp->m_user.config); - cmd += wxT(" "); - cmd += wxString(szOutFile, wxConvUTF8); - wxExecute(cmd); - } -} diff --git a/applications/osmo4_wx/fileprops.h b/applications/osmo4_wx/fileprops.h deleted file mode 100644 index a1ba51b..0000000 --- a/applications/osmo4_wx/fileprops.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Osmo4 wxWidgets GUI - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#ifndef _FILEPROPS_H -#define _FILEPROPS_H - -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include - -#include - -/*abstract class for all items in the tree*/ -class ODTreeData : public wxTreeItemData -{ -public: - ODTreeData(GF_ObjectManager *odm) : wxTreeItemData(), m_pODMan(odm) {} - GF_ObjectManager *m_pODMan; -}; - - -class wxOsmo4Frame; -class wxFileProps : public wxDialog -{ -public: - wxFileProps(wxWindow *parent); - virtual ~wxFileProps(); - -private: - DECLARE_EVENT_TABLE() - - wxOsmo4Frame *m_pApp; - - wxTreeCtrl *m_pTreeView; - wxTextCtrl *m_pViewInfo; - wxComboBox *m_pViewSel; - wxButton *m_pViewWI, *m_pViewSG; - wxTimer *m_pTimer; - - GF_ObjectManager *m_current_odm; - - void RewriteODTree(); - void SetGeneralInfo(); - void SetStreamsInfo(); - void SetDecoderInfo(); - void SetNetworkInfo(); - void WriteInlineTree(ODTreeData *pRoot); - void OnSetSelection(wxTreeEvent &event); - void OnSelectInfo(wxCommandEvent &event); - void OnTimer(wxTimerEvent &event); - void OnViewWorld(wxCommandEvent &event); - void OnViewSG(wxCommandEvent &event); - void SetInfo(GF_ObjectManager *odm); -}; - -#endif - diff --git a/applications/osmo4_wx/menubtn.cpp b/applications/osmo4_wx/menubtn.cpp deleted file mode 100644 index a13e58c..0000000 --- a/applications/osmo4_wx/menubtn.cpp +++ /dev/null @@ -1,863 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: wxMenuButton -// Purpose: A button with a dropdown wxMenu -// Author: John Labenski -// Modified by: -// Created: 11/05/2002 -// RCS-ID: -// Copyright: (c) John Labenki -// Licence: wxWidgets licence -///////////////////////////////////////////////////////////////////////////// - -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "menubtn.h" -#endif - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#ifndef WX_PRECOMP - #include "wx/control.h" - #include "wx/menu.h" - #include "wx/settings.h" - #include "wx/bitmap.h" - #include "wx/pen.h" - #include "wx/dc.h" -#endif // WX_PRECOMP - -#include -#include -#include -#include - -#include "menubtn.h" - - - -// ========================================================================== -// wxCustomButton -// ========================================================================== -IMPLEMENT_DYNAMIC_CLASS( wxCustomButton, wxControl ) - -BEGIN_EVENT_TABLE(wxCustomButton,wxControl) - EVT_MOUSE_EVENTS ( wxCustomButton::OnMouseEvents ) - EVT_PAINT ( wxCustomButton::OnPaint ) - EVT_SIZE ( wxCustomButton::OnSize ) -END_EVENT_TABLE() - -wxCustomButton::~wxCustomButton() -{ - if (HasCapture()) ReleaseMouse(); - if (m_timer) delete m_timer; -} - -void wxCustomButton::Init() -{ - m_focused = FALSE; - m_labelMargin = wxSize(4,4); - m_bitmapMargin = wxSize(2,2); - m_down = 0; - m_timer = NULL; - m_eventType = 0; - m_button_style = wxCUSTBUT_TOGGLE|wxCUSTBUT_BOTTOM; -} - -bool wxCustomButton::Create(wxWindow* parent, wxWindowID id, - const wxString& label, const wxBitmap &bitmap, - const wxPoint& pos, const wxSize& size, - long style, const wxValidator& val, - const wxString& name) -{ - if (!wxControl::Create(parent,id,pos,size,wxNO_BORDER|wxCLIP_CHILDREN,val,name)) - return FALSE; - - wxControl::SetLabel(label); - wxControl::SetBackgroundColour(parent->GetBackgroundColour()); - wxControl::SetForegroundColour(parent->GetForegroundColour()); - wxControl::SetFont(parent->GetFont()); - - if (bitmap.Ok()) m_bmpLabel = bitmap; - - if (!SetButtonStyle(style)) return FALSE; - - wxSize bestSize = DoGetBestSize(); - SetSize(wxSize(size.x<0 ? bestSize.x:size.x, size.y<0 ? bestSize.y:size.y)); -#if (wxMINOR_VERSION<8) - SetBestSize(GetSize()); -#else - SetInitialSize(GetSize()); -#endif - - CalcLayout(TRUE); - return TRUE; -} - -void wxCustomButton::SetValue(bool depressed) -{ - wxCHECK_RET(!(m_button_style & wxCUSTBUT_NOTOGGLE), wxT("can't set button state")); - m_down = depressed ? 1 : 0; - Refresh(FALSE); -} - -bool wxCustomButton::SetButtonStyle(long style) -{ - int n_styles = 0; - if ((style & wxCUSTBUT_LEFT) != 0) n_styles++; - if ((style & wxCUSTBUT_RIGHT) != 0) n_styles++; - if ((style & wxCUSTBUT_TOP) != 0) n_styles++; - if ((style & wxCUSTBUT_BOTTOM) != 0) n_styles++; - wxCHECK_MSG(n_styles < 2, FALSE, wxT("Only one wxCustomButton label position allowed")); - - n_styles = 0; - if ((style & wxCUSTBUT_NOTOGGLE) != 0) n_styles++; - if ((style & wxCUSTBUT_BUTTON) != 0) n_styles++; - if ((style & wxCUSTBUT_TOGGLE) != 0) n_styles++; - if ((style & wxCUSTBUT_BUT_DCLICK_TOG) != 0) n_styles++; - if ((style & wxCUSTBUT_TOG_DCLICK_BUT) != 0) n_styles++; - wxCHECK_MSG(n_styles < 2, FALSE, wxT("Only one wxCustomButton style allowed")); - - m_button_style = style; - - if ((m_button_style & wxCUSTBUT_BUTTON) != 0) - m_down = 0; - - CalcLayout(TRUE); - return TRUE; -} - -void wxCustomButton::SetLabel( const wxString &label ) -{ - wxControl::SetLabel(label); - CalcLayout(TRUE); -} - -// sequence of events in GTK is up, dclick, up. - -void wxCustomButton::OnMouseEvents(wxMouseEvent& event) -{ - if (m_button_style & wxCUSTBUT_NOTOGGLE) return; - - if (event.LeftDown() || event.RightDown()) - { - if (!HasCapture()) - CaptureMouse(); // keep depressed until up - - m_down++; - Redraw(); - } - else if (event.LeftDClick() || event.RightDClick()) - { - m_down++; // GTK eats second down event - Redraw(); - } - else if (event.LeftUp()) - { - if (HasCapture()) - ReleaseMouse(); - - m_eventType = wxEVT_LEFT_UP; - -#if (wxMINOR_VERSION<8) - if (wxRect(wxPoint(0,0), GetSize()).Inside(event.GetPosition())) -#else - if (wxRect(wxPoint(0,0), GetSize()).Contains(event.GetPosition())) -#endif - { - if ((m_button_style & wxCUSTBUT_BUTTON) && (m_down > 0)) - { - m_down = 0; - Redraw(); - SendEvent(); - return; - } - else - { - if (!m_timer) - { - m_timer = new wxTimer(this, m_down+1); - m_timer->Start(200, TRUE); - } - else - { - m_eventType = wxEVT_LEFT_DCLICK; - } - - if ((m_button_style & wxCUSTBUT_TOGGLE) && - (m_button_style & wxCUSTBUT_TOG_DCLICK_BUT)) m_down++; - } - } - - Redraw(); - } - else if (event.RightUp()) - { - if (HasCapture()) - ReleaseMouse(); - - m_eventType = wxEVT_RIGHT_UP; - -#if (wxMINOR_VERSION<8) - if (wxRect(wxPoint(0,0), GetSize()).Inside(event.GetPosition())) -#else - if (wxRect(wxPoint(0,0), GetSize()).Contains(event.GetPosition())) -#endif - { - if ((m_button_style & wxCUSTBUT_BUTTON) && (m_down > 0)) - { - m_down = 0; - Redraw(); - SendEvent(); - return; - } - else - { - m_down++; - - if (!m_timer) - { - m_timer = new wxTimer(this, m_down); - m_timer->Start(250, TRUE); - } - else - { - m_eventType = wxEVT_RIGHT_DCLICK; - } - } - } - - Redraw(); - } - else if (event.Entering()) - { - m_focused = TRUE; - if ((event.LeftIsDown() || event.RightIsDown()) && HasCapture()) - m_down++; - - Redraw(); - } - else if (event.Leaving()) - { - m_focused = FALSE; - if ((event.LeftIsDown() || event.RightIsDown()) && HasCapture()) - m_down--; - - Redraw(); - } -} - - - -void wxCustomButton::SendEvent() -{ - if (((m_button_style & wxCUSTBUT_TOGGLE) && (m_eventType == wxEVT_LEFT_UP)) || - ((m_button_style & wxCUSTBUT_BUT_DCLICK_TOG) && (m_eventType == wxEVT_LEFT_DCLICK)) || - ((m_button_style & wxCUSTBUT_TOG_DCLICK_BUT) && (m_eventType == wxEVT_LEFT_UP))) - { - wxCommandEvent eventOut(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, GetId()); - eventOut.SetInt(m_down%2 ? 1 : 0); - eventOut.SetExtraLong(m_eventType); - eventOut.SetEventObject(this); - GetEventHandler()->ProcessEvent(eventOut); - } - else - { - wxCommandEvent eventOut(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); - eventOut.SetInt(0); - eventOut.SetExtraLong(m_eventType); - eventOut.SetEventObject(this); - GetEventHandler()->ProcessEvent(eventOut); - } -} - -wxBitmap wxCustomButton::CreateBitmapDisabled(const wxBitmap &bitmap) const -{ - wxCHECK_MSG(bitmap.Ok(), wxNullBitmap, wxT("invalid bitmap")); - - unsigned char br = GetBackgroundColour().Red(); - unsigned char bg = GetBackgroundColour().Green(); - unsigned char bb = GetBackgroundColour().Blue(); - - wxImage image = bitmap.ConvertToImage(); - int pos, width = image.GetWidth(), height = image.GetHeight(); - unsigned char *img_data = image.GetData(); - - for (int j=0; j lh ? bh : lh; - if (has_bitmap && has_label) lw -= wxMin(m_labelMargin.x, m_bitmapMargin.x); - return wxSize(lw+bw, h); - } - - int w = bw > lw ? bw : lw; - if (has_bitmap && has_label) lh -= wxMin(m_labelMargin.y, m_bitmapMargin.y); - return wxSize(w, lh+bh); -} - -void wxCustomButton::CalcLayout(bool refresh) -{ - int w, h; - GetSize(&w,&h); - - int bw = 0, bh = 0; - int lw = 0, lh = 0; - - if (m_bmpLabel.Ok()) // assume they're all the same size - { - bw = m_bmpLabel.GetWidth(); - bh = m_bmpLabel.GetHeight(); - } - wxString label = GetLabel(); - if (!label.IsEmpty()) - { - GetTextExtent(label, &lw, &lh); - } - - // Center the label or bitmap if only one or the other - if (!m_bmpLabel.Ok()) - { - m_bitmapPos = wxPoint(0,0); - m_labelPos = wxPoint((w-lw)/2, (h-lh)/2); - } - else if (label.IsEmpty()) - { - m_bitmapPos = wxPoint((w-bw)/2, (h-bh)/2); - m_labelPos = wxPoint(0,0); - } - else if (m_button_style & wxCUSTBUT_LEFT) - { - int mid_margin = wxMax(m_labelMargin.x, m_bitmapMargin.x); - m_labelPos = wxPoint((w - (bw+lw+m_labelMargin.x+m_bitmapMargin.x+mid_margin))/2 + m_labelMargin.x, (h - lh)/2); - m_bitmapPos = wxPoint(m_labelPos.x + lw + mid_margin, (h - bh)/2); - } - else if (m_button_style & wxCUSTBUT_RIGHT) - { - int mid_margin = wxMax(m_labelMargin.x, m_bitmapMargin.x); - m_bitmapPos = wxPoint((w - (bw+lw+m_labelMargin.x+m_bitmapMargin.x+mid_margin))/2 + m_bitmapMargin.x, (h - bh)/2); - m_labelPos = wxPoint(m_bitmapPos.x + bw + mid_margin, (h - lh)/2); - } - else if (m_button_style & wxCUSTBUT_TOP) - { - int mid_margin = wxMax(m_labelMargin.y, m_bitmapMargin.y); - m_labelPos = wxPoint((w - lw)/2, (h - (bh+lh+m_labelMargin.y+m_bitmapMargin.y+mid_margin))/2 + m_labelMargin.y); - m_bitmapPos = wxPoint((w - bw)/2, m_labelPos.y + lh + mid_margin); - } - else // if (m_button_style & wxCUSTBUT_BOTTOM) DEFAULT - { - int mid_margin = wxMax(m_labelMargin.y, m_bitmapMargin.y); - m_bitmapPos = wxPoint((w - bw)/2, (h - (bh+lh+m_labelMargin.y+m_bitmapMargin.y+mid_margin))/2 + m_bitmapMargin.y); - m_labelPos = wxPoint((w - lw)/2, m_bitmapPos.y + bh + mid_margin); - } - - if (refresh) Refresh(FALSE); -} - - -/* XPM */ -static const char *down_arrow_xpm_data[] = { -/* columns rows colors chars-per-pixel */ -"5 3 2 1", -" c None", -"a c Black", -/* pixels */ -"aaaaa", -" aaa ", -" a "}; - -static wxBitmap s_dropdownBitmap; // all buttons share the same bitmap - -enum -{ - IDD_DROPDOWN_BUTTON = 100 -}; - -//----------------------------------------------------------------------------- -// wxMenuButtonEvents -//----------------------------------------------------------------------------- - -DEFINE_LOCAL_EVENT_TYPE(wxEVT_MENUBUTTON_OPEN) - -// ========================================================================== -// MenuDropButton -// ========================================================================== - -class MenuDropButton : public wxCustomButton -{ -public: - MenuDropButton( wxWindow *parent, wxWindowID id, long style) : wxCustomButton() - { - if (!s_dropdownBitmap.Ok()) - s_dropdownBitmap = wxBitmap(down_arrow_xpm_data); - - Create( parent, id, wxEmptyString, s_dropdownBitmap, wxDefaultPosition, - wxSize(wxMENUBUTTON_DROP_WIDTH, wxMENUBUTTON_DROP_HEIGHT), style); - } - - virtual void Paint( wxDC &dc ) - { - wxCustomButton *labelBut = ((wxMenuButton*)GetParent())->GetLabelButton(); - - // pretend that both buttons have focus (for flat style) - if (labelBut) - { - wxPoint p = GetParent()->ScreenToClient(wxGetMousePosition()); - -#if (wxMINOR_VERSION<8) - if (GetRect().Inside(p) || labelBut->GetRect().Inside(p)) -#else - if (GetRect().Contains(p) || labelBut->GetRect().Contains(p)) -#endif - { - m_focused = TRUE; - - if (!labelBut->GetFocused()) - labelBut->SetFocused(TRUE); - } - else - { - m_focused = FALSE; - - if (labelBut->GetFocused()) - labelBut->SetFocused(FALSE); - } - } - - wxCustomButton::Paint(dc); - } -}; - -// ========================================================================== -// MenuLabelButton -// ========================================================================== - -class MenuLabelButton : public wxCustomButton -{ -public: - MenuLabelButton( wxWindow* parent, wxWindowID id, - const wxString &label, - const wxBitmap &bitmap, - long style ) : wxCustomButton() - { - Create(parent, id, label, bitmap, wxDefaultPosition, wxDefaultSize, style); - } - - virtual void Paint( wxDC &dc ) - { - wxCustomButton *dropBut = ((wxMenuButton*)GetParent())->GetDropDownButton(); - - // pretend that both buttons have focus (for flat style) - if (dropBut) - { - wxPoint p = GetParent()->ScreenToClient(wxGetMousePosition()); - -#if (wxMINOR_VERSION<8) - if (GetRect().Inside(p) || dropBut->GetRect().Inside(p)) -#else - if (GetRect().Contains(p) || dropBut->GetRect().Contains(p)) -#endif - { - m_focused = TRUE; - - if (!dropBut->GetFocused()) - dropBut->SetFocused(TRUE); - } - else - { - m_focused = FALSE; - - if (dropBut->GetFocused()) - dropBut->SetFocused(FALSE); - } - } - - wxCustomButton::Paint(dc); - } -}; - -// ========================================================================== -// wxMenuButton -// ========================================================================== - -IMPLEMENT_DYNAMIC_CLASS( wxMenuButton, wxControl ) - -BEGIN_EVENT_TABLE(wxMenuButton,wxControl) - EVT_BUTTON(wxID_ANY, wxMenuButton::OnButton) - -#ifdef __WXMSW__ - EVT_MENU(wxID_ANY, wxMenuButton::OnMenu) -#endif -END_EVENT_TABLE() - -wxMenuButton::~wxMenuButton() -{ - AssignMenu(NULL, TRUE); -} - -void wxMenuButton::Init() -{ - m_labelButton = NULL; - m_dropdownButton = NULL; - m_menu = NULL; - m_menu_static = FALSE; - m_style = 0; -} - -bool wxMenuButton::Create( wxWindow* parent, wxWindowID id, - const wxString &label, - const wxBitmap &bitmap, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& val, - const wxString& name) -{ - m_style = style; - - long flat = style & wxMENUBUT_FLAT; - - wxControl::Create(parent,id,pos,size,wxNO_BORDER|wxCLIP_CHILDREN,val,name); - wxControl::SetLabel(label); - SetBackgroundColour(parent->GetBackgroundColour()); - SetForegroundColour(parent->GetForegroundColour()); - SetFont(parent->GetFont()); - - m_labelButton = new MenuLabelButton(this, id, label, bitmap, wxCUSTBUT_BUTTON|flat); - m_dropdownButton = new MenuDropButton(this, IDD_DROPDOWN_BUTTON, wxCUSTBUT_BUTTON|flat); - - wxSize bestSize = DoGetBestSize(); - SetSize( wxSize(size.x < 0 ? bestSize.x : size.x, - size.y < 0 ? bestSize.y : size.y) ); - -#if (wxMINOR_VERSION<8) - SetBestSize(GetSize()); -#else - SetInitialSize(GetSize()); -#endif - - return TRUE; -} - -#ifdef __WXMSW__ -// FIXME - I think there was a patch to fix this -void wxMenuButton::OnMenu( wxCommandEvent &event ) -{ - event.Skip(); - wxMenuItem *mi = m_menu->FindItem(event.GetId()); - if (mi && (mi->GetKind() == wxITEM_RADIO)) - m_menu->Check(event.GetId(), TRUE); -} -#endif // __WXMSW__ - -void wxMenuButton::OnButton( wxCommandEvent &event) -{ - int win_id = event.GetId(); - - if (win_id == IDD_DROPDOWN_BUTTON) - { - wxNotifyEvent mevent(wxEVT_MENUBUTTON_OPEN, GetId()); - mevent.SetEventObject(this); - if (GetEventHandler()->ProcessEvent(mevent) && !mevent.IsAllowed()) - return; - - if (!m_menu) - return; - - PopupMenu(m_menu, wxPoint(0, GetSize().y)); - - m_labelButton->Refresh(FALSE); - m_dropdownButton->Refresh(FALSE); - } - else if (win_id == m_labelButton->GetId()) - { - - wxCommandEvent cevent(wxEVT_COMMAND_MENU_SELECTED, win_id); - cevent.SetEventObject(this); - cevent.SetId(win_id); - GetParent()->GetEventHandler()->ProcessEvent(cevent); - - if (!m_menu) return; - - const wxMenuItemList &items = m_menu->GetMenuItems(); - int first_radio_id = -1; - int checked_id = -1; - bool check_next = FALSE; - - // find the next available radio item to check - for (wxMenuItemList::Node *node = items.GetFirst(); node; node = node->GetNext()) - { - wxMenuItem *mi = (wxMenuItem*)node->GetData(); - if (mi && (mi->GetKind() == wxITEM_RADIO)) - { - if (first_radio_id == -1) - first_radio_id = mi->GetId(); - - if (check_next) - { - check_next = FALSE; - checked_id = mi->GetId(); - break; - } - else if (mi->IsChecked()) - check_next = TRUE; - } - } - // the last item was checked, go back to the first - if (check_next && (first_radio_id != -1)) - checked_id = first_radio_id; - - if (checked_id != -1) - { - m_menu->Check(checked_id, TRUE); - - wxCommandEvent mevent( wxEVT_COMMAND_MENU_SELECTED, checked_id); - mevent.SetEventObject( m_menu ); - mevent.SetInt(1); - GetEventHandler()->ProcessEvent(mevent); - } - } -} - -int wxMenuButton::GetSelection() const -{ - wxCHECK_MSG(m_menu != NULL, wxNOT_FOUND, wxT("No attached menu in wxMenuButton::GetSelection")); - - const wxMenuItemList &items = m_menu->GetMenuItems(); - - for (wxMenuItemList::Node *node = items.GetFirst(); node; node = node->GetNext()) - { - wxMenuItem *mi = (wxMenuItem*)node->GetData(); - if (mi && (mi->GetKind() == wxITEM_RADIO)) - { - if (mi->IsChecked()) - return mi->GetId(); - } - } - - return wxNOT_FOUND; -} - -void wxMenuButton::AssignMenu(wxMenu *menu, bool static_menu) -{ - if (!m_menu_static && m_menu) - delete m_menu; - - m_menu = menu; - m_menu_static = static_menu; -} - -void wxMenuButton::SetToolTip(const wxString &tip) -{ - wxWindow::SetToolTip(tip); - ((wxWindow*)m_labelButton)->SetToolTip(tip); - ((wxWindow*)m_dropdownButton)->SetToolTip(tip); -} -void wxMenuButton::SetToolTip(wxToolTip *tip) -{ - wxWindow::SetToolTip(tip); - ((wxWindow*)m_labelButton)->SetToolTip(tip); - ((wxWindow*)m_dropdownButton)->SetToolTip(tip); -} - -void wxMenuButton::DoSetSize(int x, int y, int width, int height, int sizeFlags) -{ - wxSize curSize( GetSize() ); - wxSize bestSize( DoGetBestSize() ); - - if (width == -1) - width = curSize.GetWidth(); - if (width < 10) - width = bestSize.GetWidth(); - - if (height == -1) - height = curSize.GetHeight(); - if (height < 5) - height = bestSize.GetHeight(); - - wxWindow::DoSetSize(x, y, width, height, sizeFlags); - - if (m_labelButton) - m_labelButton->SetSize(0, 0, width - wxMENUBUTTON_DROP_WIDTH, height); - if (m_dropdownButton) - m_dropdownButton->SetSize(width-wxMENUBUTTON_DROP_WIDTH, 0, wxMENUBUTTON_DROP_WIDTH, height); -} - -wxSize wxMenuButton::DoGetBestSize() -{ - if (!m_labelButton || !m_dropdownButton) - return wxSize(wxMENUBUTTON_DROP_WIDTH+wxMENUBUTTON_DROP_HEIGHT, wxMENUBUTTON_DROP_HEIGHT); - - wxSize size = m_labelButton->GetBestSize(); - size.x += wxMENUBUTTON_DROP_WIDTH; - return size; -} diff --git a/applications/osmo4_wx/menubtn.h b/applications/osmo4_wx/menubtn.h deleted file mode 100644 index 441c7b7..0000000 --- a/applications/osmo4_wx/menubtn.h +++ /dev/null @@ -1,314 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: wxMenuButton -// Purpose: A button with a dropdown wxMenu -// Author: John Labenski -// Modified by: -// Created: 11/05/2002 -// Copyright: (c) John Labenski -// Licence: wxWidgets licence -///////////////////////////////////////////////////////////////////////////// - -/* - -wxMenuButton is a button that drops down an assigned wxMenu - -Create the button with either a text or bitmap label. - Create a new wxMenu and call AssignMenu and thats it. When you press the - dropdown button the menu appears. When you press the label button the next - wxITEM_RADIO (ie wxMenuItem::GetKind) in the menu is selected round robin. - If there are no radio items then it really just acts like a menubar, though - this is probably not too useful. The events sent in this case are EVT_MENUs - either generated by the menu when you click on it or created when you click - on the label to select the next radio item. -*/ - -#ifndef _WX_MENUBTN_H_ -#define _WX_MENUBTN_H_ - -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma interface "menubtn.h" -#endif - -class wxMenu; -class wxBitmap; -class wxCustomButton; - -//----------------------------------------------------------------------------- -// wxCustomButton styles -//----------------------------------------------------------------------------- - -enum wxCustomButton_Style -{ - // Position of the label, use only one - wxCUSTBUT_LEFT = 0x0001, - wxCUSTBUT_RIGHT = 0x0002, - wxCUSTBUT_TOP = 0x0004, - wxCUSTBUT_BOTTOM = 0x0008, - // Button style, use only one - wxCUSTBUT_NOTOGGLE = 0x0100, - wxCUSTBUT_BUTTON = 0x0200, - wxCUSTBUT_TOGGLE = 0x0400, - wxCUSTBUT_BUT_DCLICK_TOG = 0x0800, - wxCUSTBUT_TOG_DCLICK_BUT = 0x1000, - // drawing styles - wxCUSTBUT_FLAT = 0x2000 // flat, mouseover raises if not depressed -}; - -//----------------------------------------------------------------------------- -// wxCustomButton -//----------------------------------------------------------------------------- - -class WXDLLEXPORT wxCustomButton : public wxControl -{ -public: - - wxCustomButton() : wxControl() { Init(); } - - // wxToggleButton or wxButton compatible constructor (also wxTextCtrl) - wxCustomButton(wxWindow* parent, wxWindowID id, - const wxString& label, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxCUSTBUT_TOGGLE, - const wxValidator& val = wxDefaultValidator, - const wxString& name = wxT("wxCustomButton")) - : wxControl() - { - Init(); - Create(parent,id,label,wxNullBitmap,pos,size,style,val,name); - } - - // wxBitmapButton compatible constructor - wxCustomButton(wxWindow *parent, wxWindowID id, - const wxBitmap& bitmap, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxCUSTBUT_TOGGLE, - const wxValidator& val = wxDefaultValidator, - const wxString& name = wxT("wxCustomButton")) - : wxControl() - { - Init(); - Create(parent,id,wxEmptyString,bitmap,pos,size,style,val,name); - } - - // Native constructor - wxCustomButton(wxWindow *parent, wxWindowID id, - const wxString& label, const wxBitmap& bitmap, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxCUSTBUT_TOGGLE|wxCUSTBUT_BOTTOM, - const wxValidator& val = wxDefaultValidator, - const wxString& name = wxT("wxCustomButton")) - : wxControl() - { - Init(); - Create(parent,id,label,bitmap,pos,size,style,val,name); - } - - virtual ~wxCustomButton(); - - bool Create(wxWindow* parent, - wxWindowID id, - const wxString& label, - const wxBitmap &bitmap, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxValidator& val = wxDefaultValidator, - const wxString& name = wxT("wxCustomButton")); - - bool GetValue() const { return m_down%2 != 0; } - void SetValue( bool depressed ); - - // Use combinations of wxCustomButton_Style(s) - long GetButtonStyle() const { return m_button_style; } - bool SetButtonStyle( long style ); - - // Set the text label, wxEmptyString for none - void SetLabel( const wxString &label ); - - // set the bitmaps, ONLY this Label bitmap is used for calculating control size - // all bitmaps will be centered accordingly in any case - // call SetSet(GetBestSize()) if you change their size and want the control to resize appropriately - void SetBitmapLabel(const wxBitmap& bitmap); - void SetBitmapSelected(const wxBitmap& sel) { m_bmpSelected = sel; CalcLayout(TRUE); }; - void SetBitmapFocus(const wxBitmap& focus) { m_bmpFocus = focus; CalcLayout(TRUE); }; - void SetBitmapDisabled(const wxBitmap& disabled) { m_bmpDisabled = disabled; CalcLayout(TRUE); }; - // wxBitmapButton compatibility - void SetLabel(const wxBitmap& bitmap) { SetBitmapLabel(bitmap); } - - // retrieve the bitmaps - const wxBitmap& GetBitmapLabel() const { return m_bmpLabel; } - const wxBitmap& GetBitmapSelected() const { return m_bmpSelected; } - const wxBitmap& GetBitmapFocus() const { return m_bmpFocus; } - const wxBitmap& GetBitmapDisabled() const { return m_bmpDisabled; } - - // Creates a "disabled" bitmap by dithering it with the background colour - wxBitmap CreateBitmapDisabled(const wxBitmap &bitmap) const; - - // set/get the margins (in pixels) around the label and bitmap - // if fit = TRUE then resize the button to fit - void SetMargins(const wxSize &margin, bool fit = FALSE); - - // set/get the margins around the text label - // the inter bitmap/label margin is the max of either margin, not the sum - void SetLabelMargin(const wxSize &margin, bool fit = FALSE); - wxSize GetLabelMargin() const { return m_labelMargin; } - // set/get the margins around the bitmap - // the inter bitmap/label margin is the max of either margin, not the sum - void SetBitmapMargin(const wxSize &margin, bool fit = FALSE); - wxSize GetBitmapMargin() const { return m_bitmapMargin; } - - // can be used to activate the focused behavior (see MenuButton) - void SetFocused(bool focused) { m_focused = focused; Refresh(FALSE); } - bool GetFocused() const { return m_focused; } - -protected: - void OnPaint(wxPaintEvent &event); - void Redraw(); - virtual void Paint( wxDC &dc ); - - virtual wxSize DoGetBestSize() const; - - virtual void SendEvent(); - - void OnMouseEvents(wxMouseEvent &event); - - void OnSize( wxSizeEvent &event ); - - virtual void CalcLayout(bool refresh); - - long m_down; // toggle state if m_down%2 then depressed - bool m_focused; // mouse in window - long m_button_style; - - // the bitmaps for various states - wxBitmap m_bmpLabel, - m_bmpSelected, - m_bmpFocus, - m_bmpDisabled; - - // the margins around the label/bitmap - wxSize m_labelMargin, - m_bitmapMargin; - - wxPoint m_bitmapPos, - m_labelPos; - - wxTimer *m_timer; - - wxEventType m_eventType; // store the mouse event type - -private: - void Init(); - DECLARE_DYNAMIC_CLASS(wxCustomButton) - DECLARE_EVENT_TABLE() -}; - -//----------------------------------------------------------------------------- -// wxMenuButton styles -//----------------------------------------------------------------------------- - -#define wxMENUBUTTON_DROP_WIDTH 10 -#define wxMENUBUTTON_DROP_HEIGHT 22 - -enum wxMenuButton_Styles -{ - wxMENUBUT_FLAT = wxCUSTBUT_FLAT -}; - -//----------------------------------------------------------------------------- -// wxMenuButton -//----------------------------------------------------------------------------- - -class wxMenuButton : public wxControl -{ -public: - - wxMenuButton() : wxControl() { Init(); } - - // Use this constructor if you need one compatible with a wxBitmapButton - // setup the button later with AssignMenu - wxMenuButton( wxWindow* parent, wxWindowID id, - const wxBitmap &bitmap, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxValidator& val = wxDefaultValidator, - const wxString& name = wxT("wxMenuButton")) - : wxControl() - { - Init(); - Create(parent,id,wxEmptyString,bitmap,pos,size,style,val,name); - } - - virtual ~wxMenuButton(); - - bool Create( wxWindow* parent, - wxWindowID id, - const wxString &label, - const wxBitmap &bitmap, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER, - const wxValidator& val = wxDefaultValidator, - const wxString& name = wxT("wxMenuButton")); - - // Gets the id of the first selected radio item or wxNOT_FOUND (-1) if none - int GetSelection() const; - - // This menu will be displayed when the dropdown button is pressed. - // if static_menu is FALSE it will be deleted when the buttton is destroyed. - void AssignMenu(wxMenu *menu, bool static_menu = FALSE); - - wxMenu *GetMenu() const { return m_menu; } - - // get a pointer to the label button, for turning it into a toggle perhaps - wxCustomButton *GetLabelButton() const { return m_labelButton; } - wxCustomButton *GetDropDownButton() const { return m_dropdownButton; } - - void SetToolTip(const wxString &tip); - void SetToolTip(wxToolTip *tip); - -protected: - void OnButton(wxCommandEvent &event); - - virtual void DoSetSize(int x, int y, int width, int height, - int sizeFlags = wxSIZE_AUTO); - - virtual wxSize DoGetBestSize(); - -// FIXME! - in MSW the radio items don't check themselves -#ifdef __WXMSW__ - void OnMenu( wxCommandEvent &event ); -#endif - - wxCustomButton *m_labelButton; - wxCustomButton *m_dropdownButton; - - wxMenu *m_menu; - bool m_menu_static; - long m_style; - -private: - void Init(); - DECLARE_DYNAMIC_CLASS(wxMenuButton) - DECLARE_EVENT_TABLE() -}; - -//----------------------------------------------------------------------------- -// wxMenuButtonEvents -// -// EVT_MENUBUTTON_OPEN(id, fn) - menu is about to be opened, (dis)(en)able items -// or call Veto() to stop menu from popping up -// this is a wxNotifyEvent -//----------------------------------------------------------------------------- - -BEGIN_DECLARE_EVENT_TYPES() - DECLARE_LOCAL_EVENT_TYPE( wxEVT_MENUBUTTON_OPEN, 0 ) -END_DECLARE_EVENT_TYPES() - -#define EVT_MENUBUTTON_OPEN(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_MENUBUTTON_OPEN, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) & fn, (wxObject *) NULL ), - -#endif // _WX_MENUBTN_H_ diff --git a/applications/osmo4_wx/osmo4.ico b/applications/osmo4_wx/osmo4.ico deleted file mode 100644 index 36ff66711771065305f263aee09bda915091c6b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 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 Ih+0ATC&$&)D*ylh diff --git a/applications/osmo4_wx/osmo4.xpm b/applications/osmo4_wx/osmo4.xpm deleted file mode 100644 index bec8e6a..0000000 --- a/applications/osmo4_wx/osmo4.xpm +++ /dev/null @@ -1,301 +0,0 @@ -/* XPM */ -static const char * osmo4[] = { -"32 32 266 2", -" c None", -". c #990909", -"+ c #A10505", -"@ c #AB0404", -"# c #AF0202", -"$ c #B10303", -"% c #AE0202", -"& c #A90505", -"* c #A10606", -"= c #990E0E", -"- c #990D0D", -"; c #A80303", -"> c #BD0000", -", c #D40000", -"' c #DE0000", -") c #E20000", -"! c #E10000", -"~ c #DC0000", -"{ c #CD0000", -"] c #B80101", -"^ c #A40909", -"/ c #A20505", -"( c #BD0101", -"_ c #E00000", -": c #CB0000", -"< c #A80000", -"[ c #7E0101", -"} c #6B0202", -"| c #670202", -"1 c #720202", -"2 c #920000", -"3 c #B70000", -"4 c #D70000", -"5 c #B80303", -"6 c #9D0B0B", -"7 c #980909", -"8 c #B00202", -"9 c #DB0000", -"0 c #B50909", -"a c #8A1313", -"b c #1C0505", -"c c #070505", -"d c #080808", -"e c #0A0A0A", -"f c #090909", -"g c #070707", -"h c #0C0404", -"i c #5B1414", -"j c #A70F0F", -"k c #CC0303", -"l c #CC0000", -"m c #AB0505", -"n c #950D0D", -"o c #B60101", -"p c #DD0000", -"q c #CF0202", -"r c #9C1414", -"s c #141414", -"t c #0C0C0C", -"u c #0F0F0F", -"v c #111111", -"w c #101010", -"x c #0E0E0E", -"y c #B70707", -"z c #DF0000", -"A c #D50000", -"B c #A90606", -"C c #970E0E", -"D c #B30202", -"E c #C50505", -"F c #812121", -"G c #191919", -"H c #161616", -"I c #181818", -"J c #171717", -"K c #151515", -"L c #AF0A0A", -"M c #D70101", -"N c #D60000", -"O c #AD0606", -"P c #AA0303", -"Q c #DA0000", -"R c #C80505", -"S c #8E1E1E", -"T c #1D1D1D", -"U c #1F1F1F", -"V c #202020", -"W c #B00909", -"X c #CE0000", -"Y c #9F0A0A", -"Z c #9B0808", -"` c #D20000", -" . c #D80101", -".. c #8B1B1B", -"+. c #2D2D2D", -"@. c #272727", -"#. c #262626", -"$. c #252525", -"%. c #BB0606", -"&. c #BB0303", -"*. c #AF0303", -"=. c #AF0B0B", -"-. c #303030", -";. c #2B2B2B", -">. c #323232", -",. c #CD0202", -"'. c #A60A0A", -"). c #9E0909", -"!. c #CF0000", -"~. c #CE0404", -"{. c #292929", -"]. c #B10808", -"^. c #A70303", -"/. c #B60A0A", -"(. c #961010", -"_. c #B90000", -":. c #9C1212", -"<. c #1A1A1A", -"[. c #222222", -"}. c #1C1C1C", -"|. c #C20202", -"1. c #A30606", -"2. c #C60000", -"3. c #2A2A2A", -"4. c #3B3B3B", -"5. c #444444", -"6. c #434343", -"7. c #3A3A3A", -"8. c #1E1E1E", -"9. c #131313", -"0. c #BB0A0A", -"a. c #AD0707", -"b. c #9A1515", -"c. c #D30000", -"d. c #353535", -"e. c #484848", -"f. c #5F5F5F", -"g. c #6C6C6C", -"h. c #646464", -"i. c #565656", -"j. c #343434", -"k. c #212121", -"l. c #121212", -"m. c #B30505", -"n. c #B10404", -"o. c #9A1111", -"p. c #424242", -"q. c #555555", -"r. c #6B6B6B", -"s. c #757575", -"t. c #6E6E6E", -"u. c #606060", -"v. c #4E4E4E", -"w. c #3F3F3F", -"x. c #2C2C2C", -"y. c #B10909", -"z. c #B60707", -"A. c #9B1515", -"B. c #D00000", -"C. c #494949", -"D. c #595959", -"E. c #676767", -"F. c #696969", -"G. c #616161", -"H. c #525252", -"I. c #454545", -"J. c #B20707", -"K. c #363636", -"L. c #626262", -"M. c #5B5B5B", -"N. c #505050", -"O. c #282828", -"P. c #B80B0B", -"Q. c #AC0707", -"R. c #AA1111", -"S. c #0D0D0D", -"T. c #585858", -"U. c #545454", -"V. c #4B4B4B", -"W. c #BF0303", -"X. c #9F0B0B", -"Y. c #B90707", -"Z. c #242424", -"`. c #313131", -" + c #3E3E3E", -".+ c #474747", -"++ c #4D4D4D", -"@+ c #4F4F4F", -"#+ c #4C4C4C", -"$+ c #3D3D3D", -"%+ c #D90000", -"&+ c #8E1010", -"*+ c #A00808", -"=+ c #D00303", -"-+ c #3C3C3C", -";+ c #0B0B0B", -">+ c #AE0808", -",+ c #C10101", -"'+ c #BB0202", -")+ c #BA0A0A", -"!+ c #1B1B1B", -"~+ c #2F2F2F", -"{+ c #C10303", -"]+ c #A10A0A", -"^+ c #9F0707", -"/+ c #D80000", -"(+ c #BE0303", -"_+ c #821C1C", -":+ c #C20404", -"<+ c #232323", -"[+ c #A90C0C", -"}+ c #970C0C", -"|+ c #960E0E", -"1+ c #BE0101", -"2+ c #C60505", -"3+ c #131212", -"4+ c #B00B0B", -"5+ c #CE0101", -"6+ c #A80707", -"7+ c #990B0B", -"8+ c #C40404", -"9+ c #AD0909", -"0+ c #D00101", -"a+ c #B00505", -"b+ c #7B1C1C", -"c+ c #960C0C", -"d+ c #BC0202", -"e+ c #BC0808", -"f+ c #962525", -"g+ c #482E2E", -"h+ c #1E1616", -"i+ c #141010", -"j+ c #2F2020", -"k+ c #703636", -"l+ c #A81212", -"m+ c #A90707", -"n+ c #8E1313", -"o+ c #D30606", -"p+ c #B91E1E", -"q+ c #901919", -"r+ c #661010", -"s+ c #540F0F", -"t+ c #4F0D0D", -"u+ c #5A0F0F", -"v+ c #7A1515", -"w+ c #A21E1E", -"x+ c #C51212", -"y+ c #D60101", -"z+ c #980D0D", -"A+ c #930C0C", -"B+ c #B30404", -"C+ c #C60202", -"D+ c #7B1919", -"E+ c #8C1515", -"F+ c #9F0909", -"G+ c #B20303", -"H+ c #C30000", -"I+ c #CA0000", -"J+ c #C90000", -"K+ c #BC0101", -"L+ c #AA0505", -"M+ c #8F1111", -"N+ c #7F1E1E", -"O+ c #732626", -"P+ c #762A2A", -"Q+ c #6E2828", -" ", -" . + @ # $ % & * = ", -" - ; > , ' ) ) ! ) ! ~ { ] ^ ", -" / ( ' _ : < [ } | 1 2 3 4 ) , 5 6 ", -" 7 8 9 ' 0 a b c d e e f g h i j k ) l m ", -" n o p q r s t u v v w t x y z A B ", -" C D ) E F G H I G J K L M N O ", -" P Q R S T U U T V W ' X Y ", -" Z ` ... +.@.#.$. %.! &. ", -" *.) =. -.;.>. ,.4 '. ", -" ).!.~. {. ].) ( ", -" ^.z /. $. A ` (. ", -" _.! :. K K <.V [.}.K K |.z 1. ", -" 2.9 v <.3.4.5.6.7.;.8.9.J 0.) a. ", -" b.!.c. w }.d.e.f.g.h.i.5.j.k.l. m._ n. ", -" o.` !. u J 3.p.q.r.s.t.u.v.w.x.T w y._ z. ", -" A.B.` u k.j.C.D.E.g.F.G.H.I.j.$.9.l. m._ J. ", -" : 4 s v #.K.C.q.u.h.L.M.N.I.K.O.J x P.) Q. ", -" > z R. S.9.#.d.5.v.i.D.T.U.V.p.j.{.G t W._ X. ", -" % ) Y. l.9.Z.`. +.+++N.@+#+I.$+>.@.I t { %+&+ ", -" *+, =+ x w V ;.K.$+6.I.I.p.-+K.;.[.H ;+ >+z ,+ ", -" '+_ )+ x S.!+Z.~+d.7.-+-+7.d.~+#.8.9.;+ {+_ ]+ ", -" ^+/+, e s }.$.;.~+`.`.-.;.#.U J S.w z.' (+_+ ", -" ] ) :+ t S.K T [.@.O.O.@.<+U I v ;+ [+` ~ }+ ", -" |+1+) 2+ e t 9.I }.T 8.}.G K u e 3+ 4+5+' 6+ ", -" 7+l ) 8+ e ;+u 9.K K 9.v S.f w 9+0+) a+b+ ", -" c+d+) N e+f+g+h+;+f e f i+j+k+l+|.~ /+m+ ", -" n+D N ! o+p+q+r+s+t+u+v+w+x+y+! X z+ ", -" A+B+X _ ! ~ /+N %+' ) ~ C+Y D+ ", -" E+F+G+H+I+l J+K+L+M+N+ ", -" O+P+Q+ ", -" "}; diff --git a/applications/osmo4_wx/playlist.xpm b/applications/osmo4_wx/playlist.xpm deleted file mode 100644 index cfad2dc..0000000 --- a/applications/osmo4_wx/playlist.xpm +++ /dev/null @@ -1,158 +0,0 @@ -/* XPM */ -static const char* pl_open[] = { -"16 16 5 1", -" c #000000", -"! c #808000", -"# c #C0C0C0", -"$ c #FFFF00", -"% c #FFFFFF", -"################", -"################", -"######### ####", -"######## ### # #", -"############# #", -"# ######## #", -" %$% #####", -" $%$%$%$%$ #####", -" %$%$%$%$% #####", -" $%$% #", -" %$% !!!!!!!!! #", -" $% !!!!!!!!! ##", -" % !!!!!!!!! ###", -" !!!!!!!!! ####", -" #####", -"################"}; - -/* XPM */ -static const char* pl_save[] = { -"16 16 3 1", -" c #000000", -"! c #808000", -"# c #C0C0C0", -"################", -"# #", -"# ! ######## # #", -"# ! ######## #", -"# ! ######## ! #", -"# ! ######## ! #", -"# ! ######## ! #", -"# ! ######## ! #", -"# !! !! #", -"# !!!!!!!!!!!! #", -"# !! ! #", -"# !! ## ! #", -"# !! ## ! #", -"# !! ## ! #", -"## #", -"################"}; - -/* XPM */ -static const char* pl_add[] = { -"16 16 2 1", -" c #000000", -"! c #C0C0C0", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!! !!!", -"!! !!!", -"!! !!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* pl_rem[] = { -"16 16 2 1", -" c #000000", -"! c #C0C0C0", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!! !!!", -"!! !!!", -"!! !!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* pl_up[] = { -"16 16 2 1", -" c #000000", -"! c #C0C0C0", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!! !!!!!!!!", -"!!!!!! !!!!!!!", -"!!!!! !!!!!!", -"!!!! !!!!!", -"!!! !!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* pl_down[] = { -"16 16 2 1", -" c #000000", -"! c #C0C0C0", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!!!!! !!!!!!!", -"!!! !!!!", -"!!!! !!!!!", -"!!!!! !!!!!!", -"!!!!!! !!!!!!!", -"!!!!!!! !!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* pl_sort[] = { -"16 16 2 1", -" c #000000", -"! c #C0C0C0", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!! !!!!! !!!!!", -"!!!! !!!! !!!!", -"!!!! !!! !!!", -"!!!! !!!!! !!!!!", -"!!!! !!!!! !!!!!", -"!!!! !!!!! !!!!!", -"!!!! !!!!! !!!!!", -"!! !!! !!!!!", -"!!! !!!! !!!!!", -"!!!! !!!!! !!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - diff --git a/applications/osmo4_wx/resource.h b/applications/osmo4_wx/resource.h deleted file mode 100644 index ace6dd4..0000000 --- a/applications/osmo4_wx/resource.h +++ /dev/null @@ -1,16 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by wxOsmo4.rc -// -#define IDI_OSMO_ICON 101 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 104 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/applications/osmo4_wx/toolbar.xpm b/applications/osmo4_wx/toolbar.xpm deleted file mode 100644 index 887d59e..0000000 --- a/applications/osmo4_wx/toolbar.xpm +++ /dev/null @@ -1,254 +0,0 @@ -/* XPM */ -static const char* tool_open_file[] = { -"16 16 2 1", -" c #000000", -"! c none", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!! !!!!!!!", -"!!!!!! !!!!!!", -"!!!!! !!!!!", -"!!!! !!!!", -"!!! !!!", -"!! !!", -"!! !!", -"!!!!!!!!!!!!!!!!", -"!! !!", -"!! !!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* tool_prev[] = { -"16 16 3 1", -" c #000000", -"! c none", -"# c #FF0000", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!! !!", -"!!!!!!!!!! !!", -"!!!!!!!! ## !!", -"!!!!!! #### !!", -"!!!! ###### !!", -"!!! ######## !!", -"!!!! ##### !!", -"!!!!!! ### !!", -"!!!!!!!! # !!", -"!!!!!!!!!! !!", -"!!!!!!!!!!!! !!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* tool_next[] = { -"16 16 3 1", -" c #000000", -"! c none", -"# c #FF0000", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!! !!!!!!!!!!!!", -"!! !!!!!!!!!!", -"!! ## !!!!!!!!", -"!! #### !!!!!!", -"!! ###### !!!!", -"!! ######## !!!", -"!! ###### !!!!", -"!! #### !!!!!!", -"!! ## !!!!!!!!", -"!! !!!!!!!!!!", -"!! !!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* tool_play[] = { -"16 16 2 1", -" c #000000", -"! c none", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!! !!!!!!!!!!!!", -"!! !!!!!!!!!!", -"!! !!!!!!!!", -"!! !!!!!!", -"!! !!!!", -"!! !!", -"!! !!!!", -"!! !!!!!!", -"!! !!!!!!!!", -"!! !!!!!!!!!!", -"!! !!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* tool_pause[] = { -"16 16 3 1", -" c #000000", -"! c #808080", -"# c none", -"################", -"################", -"################", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"### !##! ###", -"################", -"################"}; - - -/* XPM */ -static const char* tool_step[] = { -"16 16 2 1", -" c #000000", -"! c none", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!! !!!!!!!!!!!", -"!! !!!!!!!!!", -"!! !!!!!!!", -"!!!! !!!!!", -"!!!!!! !!!", -"!!!!!!!! !!", -"!!!!!! !!!", -"!!!! !!!!!", -"!! !!!!!!!", -"!! !!!!!!!!!", -"!! !!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - - -/* XPM */ -static const char* tool_stop[] = { -"16 16 2 1", -" c #000000", -"! c none", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!", -"!! !!", -"!! !!", -"!! !!", -"!! !!", -"!! !!", -"!! !!", -"!! !!", -"!! !!", -"!! !!", -"!! !!", -"!! !!", -"!!!!!!!!!!!!!!!!", -"!!!!!!!!!!!!!!!!"}; - -/* XPM */ -static const char* tool_info[] = { -"16 16 3 1", -" c #000000", -"! c none", -"# c #0000FF", -"!!!!!!!!!!!!!!!!", -"!!!!! !!!!!", -"!!! !!!", -"!! ###### !!", -"! ####!!#### !", -"! ####!!#### !", -" ############ ", -" #####!!##### ", -" ######!!##### ", -" #####!!##### ", -" #####!!##### ", -"! ####!!#### !", -"! #####!!### !", -"!! ###### !!", -"!!! !!!", -"!!!!! !!!!!"}; - - -/* XPM */ -static const char* tool_config[] = { -"16 16 3 1", -" c #000000", -"! c #808080", -"# c none", -"################", -"################", -"## ## ######", -"## ## # ## # ##", -"## ## #", -"## #!# ####### #", -"## # #!# ## ## #", -"## #!# #!# ! # #", -"## # #!# ## ## #", -"## #!# #!##### #", -"## # #!# ## ## #", -"## #!# #!# ! # #", -"## # #!# ## ## #", -"## #", -"################", -"################"}; - -/* XPM */ -static const char* tool_sw_2d[] = { -"16 16 4 1", -" c #FF0000", -". c #C0C0C0", -"+ c #0000FF", -"@ c #000000", -" .............. ", -". ..++..++++.. .", -".. +..+..+..+ ..", -"... ..+..+.. ...", -".... +...+. +...", -"...+. +..+ .+...", -"...+++ .+ ++....", -"....... .......", -"....@@ @@ @.....", -"...@. .@.@ .....", -"...@ ....@. ....", -"... ..@@.@.. ...", -".. @...@.@.@. ..", -". ..@@@@@@@@.. .", -" .............. ", -"................"}; - -/* XPM */ -static const char* tool_sw_3d[] = { -"16 16 4 1", -" c #FFFFFF", -". c #C0C0C0", -"+ c #0000FF", -"@ c #000000", -" ", -"................", -"....++..++++....", -"...+..+..+..+...", -"......+..+..+...", -"....++...+..+...", -"...+..+..+..+...", -"...++++.++++....", -"................", -"....@@@@@@@.....", -"...@...@.@......", -"...@.....@......", -"...@..@@.@......", -"...@...@.@.@....", -"....@@@@@@@@....", -"................"}; - diff --git a/applications/osmo4_wx/wxGPACControl.cpp b/applications/osmo4_wx/wxGPACControl.cpp deleted file mode 100644 index 7d16802..0000000 --- a/applications/osmo4_wx/wxGPACControl.cpp +++ /dev/null @@ -1,1031 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Osmo4 wxWidgets GUI - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#include "wxOsmo4.h" -#include -#include -#include -#include -#include -#include - -#include - -#include "wxGPACControl.h" - - -#define NUM_RATES 11 -static const char *BIFSRates[11] = -{ - "5.0", - "7.5", - "10.0", - "12.5", - "15.0", - "24.0", - "25.0", - "30.0", - "50.0", - "60.0", - "100.0" -}; - -void wxGPACControl::SetYUVLabel() -{ - u32 yuv_format = gf_term_get_option(m_pApp->m_term, GF_OPT_YUV_FORMAT); - if (!yuv_format) { - m_yuvtxt->SetLabel(wxT("(No YUV used)")); - } else { - char str[100]; - sprintf(str, "(%s used)", gf_4cc_to_str(yuv_format)); - m_yuvtxt->SetLabel(wxString(str, wxConvUTF8) ); - } -} - -wxGPACControl::wxGPACControl(wxWindow *parent) - : wxDialog(parent, -1, wxString(wxT("GPAC Control Panel"))) -{ - const char *sOpt; - SetSize(320, 240); - u32 i; - wxBoxSizer *bs; - Centre(); - - m_pApp = (wxOsmo4Frame *)parent; - - s_main = new wxBoxSizer(wxVERTICAL); - - s_header = new wxBoxSizer(wxHORIZONTAL); - //s_header->Add(new wxStaticText(this, 0, wxT("Category"), wxDefaultPosition, wxSize(60, 20)), wxALIGN_CENTER); - m_select = new wxComboBox(this, ID_SELECT, wxT(""), wxDefaultPosition, wxSize(120, 30), 0, NULL, wxCB_READONLY); - s_header->Add(m_select, 2, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_header->Add( new wxButton(this, ID_APPLY, wxT("Apply"), wxDefaultPosition, -#ifdef WIN32 - wxSize(40, 20) -#else - wxSize(40, 30) -#endif - ), - 1, wxALIGN_TOP|wxALIGN_RIGHT|wxADJUST_MINSIZE); - s_main->Add(s_header, 0, wxEXPAND, 0); - - /*general section*/ - s_general = new wxBoxSizer(wxVERTICAL); - m_loop = new wxCheckBox(this, 0, wxT("Loop at End"), wxPoint(10, 40), wxSize(140, 20)); - s_general->Add(m_loop); - m_lookforsubs = new wxCheckBox(this, 0, wxT("Look for Subtitles"), wxPoint(180, 40), wxSize(140, 20)); - s_general->Add(m_lookforsubs); - m_noconsole = new wxCheckBox(this, 0, wxT("Disable console messages"), wxPoint(10, 80), wxSize(180, 20)); - s_general->Add(m_noconsole); - m_viewxmt = new wxCheckBox(this, 0, wxT("View graph in XMT-A format"), wxPoint(10, 120), wxSize(180, 20)); - s_general->Add(m_viewxmt); - s_main->Add(s_general, 0, wxEXPAND, 0); - - /*MPEG-4 systems*/ - s_mpeg4 = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Prefered Stream Language")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_lang = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_lang, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_mpeg4->Add(bs, 0, wxALL|wxEXPAND, 2); - - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Decoder Threading Mode")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_thread = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_thread, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_mpeg4->Add(bs, 0, wxALL|wxEXPAND, 2); - m_bifsalwaysdrawn = new wxCheckBox(this, 0, wxT("Always draw late BIFS frames")); - s_mpeg4->Add(m_bifsalwaysdrawn); - m_singletime = new wxCheckBox(this, 0, wxT("Force Single Timeline")); - s_mpeg4->Add(m_singletime); - s_main->Add(s_mpeg4, 0, wxEXPAND, 0); - - /*media decoders*/ - s_mdec = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Prefered Audio Output")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_decaudio = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_decaudio, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_mdec->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Prefered Video Output")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_decvideo = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_decvideo, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_mdec->Add(bs, 0, wxALL|wxEXPAND, 2); - s_main->Add(s_mdec, 0, wxEXPAND, 0); - - /*Rendering*/ - s_rend = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Target Frame Rate")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_fps = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_fps, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Anti-Aliasing")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_aa = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_aa, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Graphics Driver")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_graph = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_graph, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - m_draw_bounds = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(new wxStaticText(this, 0, wxT("Bounds")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - bs->Add(m_draw_bounds, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); - m_fast = new wxCheckBox(this, 0, wxT("Fast Rendering")); - m_force_size = new wxCheckBox(this, 0, wxT("Force Scene Size")); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(m_fast, wxALIGN_CENTER | wxADJUST_MINSIZE); - bs->Add(m_force_size, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); - m_use3D = new wxCheckBox(this, 0, wxT("Use 3D Renderer")); - s_rend->Add(m_use3D, 0, wxALL|wxEXPAND, 2); - m_bWas3D = m_use3D->GetValue(); - s_main->Add(s_rend, 0, wxEXPAND, 0); - - /*Render 2D*/ - s_rend2d = new wxBoxSizer(wxVERTICAL); - m_direct = new wxCheckBox(this, 0, wxT("Direct Rendering")); - s_rend2d->Add(m_direct, 0, wxALL|wxEXPAND, 2); - m_scalable = new wxCheckBox(this, 0, wxT("Scalable Zoom")); - s_rend2d->Add(m_scalable, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - m_noyuv = new wxCheckBox(this, 0, wxT("Disable YUV hardware")); - bs->Add(m_noyuv, wxALIGN_CENTER | wxADJUST_MINSIZE); - m_yuvtxt = new wxStaticText(this, 0, wxT("(No YUV used)"), wxDefaultPosition, wxSize(60, 20), wxALIGN_LEFT); - bs->Add(m_yuvtxt, wxALIGN_CENTER|wxADJUST_MINSIZE); - s_rend2d->Add(bs, 0, wxALL|wxEXPAND, 2); - s_main->Add(s_rend2d, 0, wxEXPAND, 0); - - /*Render 3D*/ - s_rend3d = new wxBoxSizer(wxVERTICAL); - m_raster_outlines = new wxCheckBox(this, 0, wxT("Use OpenGL Raster outlines")); - s_rend3d->Add(m_raster_outlines, 0, wxALL|wxEXPAND, 2); - m_polyaa = new wxCheckBox(this, 0, wxT("Enable polygon anti-aliasing")); - s_rend3d->Add(m_polyaa, 0, wxALL|wxEXPAND, 2); - m_nobackcull = new wxCheckBox(this, 0, wxT("Disable backface culling")); - s_rend3d->Add(m_nobackcull, 0, wxALL|wxEXPAND, 2); - - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Wireframe mode")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_wire = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_wire, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rend3d->Add(bs, 0, wxALL|wxEXPAND, 2); - - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Draw Normals")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_normals = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_normals, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rend3d->Add(bs, 0, wxALL|wxEXPAND, 2); - - m_emulpow2 = new wxCheckBox(this, 0, wxT("Emulate power-of-two textures for video")); - s_rend3d->Add(m_emulpow2, 0, wxALL|wxEXPAND, 2); - m_norectext = new wxCheckBox(this, 0, wxT("Disable rectangular texture extensions")); - s_rend3d->Add(m_norectext, 0, wxALL|wxEXPAND, 2); - m_copypixels = new wxCheckBox(this, 0, wxT("Bitmap node uses direct pixel copy")); - s_rend3d->Add(m_copypixels, 0, wxALL|wxEXPAND, 2); - s_main->Add(s_rend3d, 0, wxEXPAND, 0); - - /*video*/ - s_video = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Video Driver")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - m_video = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_video , wxALIGN_CENTER | wxADJUST_MINSIZE); - s_video->Add(bs, 0, wxALL|wxEXPAND, 2); - m_switchres = new wxCheckBox(this, 0, wxT("Change video resolution in fullscreen")); - s_video->Add(m_switchres, 0, wxALL|wxEXPAND, 2); - m_usehwmem = new wxCheckBox(this, 0, wxT("Use hardware memory in 2D mode")); - s_video->Add(m_usehwmem, 0, wxALL|wxEXPAND, 2); - s_main->Add(s_video, 0, wxEXPAND, 0); - - - /*audio*/ - s_audio = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Audio Driver")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_audio = new wxComboBox(this, ID_AUDIO_DRIVER, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_audio, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_audio->Add(bs, 0, wxALL|wxEXPAND, 2); - m_forcecfg = new wxCheckBox(this, ID_FORCE_AUDIO, wxT("Force Audio Config")); - m_forcecfg->SetValue(1); - s_audio->Add(m_forcecfg, 0, wxALL|wxEXPAND, 2); - - - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Number of buffers")), wxALIGN_CENTER|wxADJUST_MINSIZE); - m_nbbuf = new wxSpinCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(20, 20), wxSP_WRAP | wxSP_ARROW_KEYS, 1, 30, 15); - m_nbbuf->SetValue(8); - bs->Add(m_nbbuf, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_audio->Add(bs, 0, wxALL|wxEXPAND, 2); - - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Total length in ms")), wxALIGN_CENTER | wxADJUST_MINSIZE); - m_buflen = new wxSpinCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(20, 20), wxSP_WRAP | wxSP_ARROW_KEYS, 1, 1000); - m_buflen->SetValue(400); - bs->Add(m_buflen, wxALIGN_CENTER | wxADJUST_MINSIZE|wxLEFT,10); - s_audio->Add(bs, 0, wxALL|wxEXPAND, 2); - - m_noresync = new wxCheckBox(this, -1, wxT("Disable Resynchronization")); - s_audio->Add(m_noresync); - m_nomulitch = new wxCheckBox(this, -1, wxT("Disable Multichannel")); - s_audio->Add(m_nomulitch); -#ifdef WIN32 - m_notifs = new wxCheckBox(this, -1, wxT("Disable DirectSound Notifications")); - s_audio->Add(m_notifs); -#endif - s_main->Add(s_audio, 0, wxEXPAND, 0); - - /*font*/ - s_font = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Font Engine")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - m_font = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_font, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_font->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("System Font Directory")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - m_fontdir = new wxButton(this, ID_FONT_DIR, wxT("..."), wxDefaultPosition, wxDefaultSize); - bs->Add(m_fontdir, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_font->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Text Texturing Mode")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - m_texturemode = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - bs->Add(m_texturemode, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_font->Add(bs, 0, wxALL|wxEXPAND, 2); - s_main->Add(s_font, 0, wxEXPAND, 0); - - /*download*/ - s_dnld = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Cache Directory")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - m_cachedir = new wxButton(this, ID_CACHE_DIR, wxT("...")); - bs->Add(m_cachedir, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_dnld->Add(bs, 0, wxALL|wxEXPAND, 2); - m_cleancache = new wxCheckBox(this, -1, wxT("Remove temp files on exit")); - s_dnld->Add(m_cleancache); - m_restartcache = new wxCheckBox(this, -1, wxT("Always redownload incomplete cached files")); - s_dnld->Add(m_restartcache); - bs = new wxBoxSizer(wxHORIZONTAL); - m_progressive = new wxCheckBox(this, ID_PROGRESSIVE, wxT("XML progressive load")); - bs->Add(m_progressive, wxALIGN_CENTER | wxADJUST_MINSIZE); - m_sax_duration = new wxTextCtrl(this, 0, wxT(""), wxPoint(10, 120), wxSize(60, 20)); - bs->Add(m_sax_duration, wxALIGN_CENTER | wxADJUST_MINSIZE); - bs->Add(new wxStaticText(this, 0, wxT("max load slice (ms)")), wxADJUST_MINSIZE | wxALIGN_CENTER); - s_dnld->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - m_use_proxy = new wxCheckBox(this, ID_USE_PROXY, wxT("Use proxy")); - bs->Add(m_use_proxy, wxALIGN_CENTER | wxADJUST_MINSIZE); - m_proxy_name = new wxTextCtrl(this, 0, wxT(""), wxPoint(10, 120), wxSize(60, 20)); - bs->Add(m_proxy_name, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_dnld->Add(bs, 0, wxALL|wxEXPAND, 2); - s_main->Add(s_dnld, 0, wxEXPAND, 0); - - /*streaming*/ - s_stream = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Default RTSP port")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - m_port = new wxComboBox(this, ID_RTSP_PORT, wxT(""), wxPoint(160, 40), wxSize(140, 30), 0, NULL, wxCB_READONLY); - bs->Add(m_port, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); - m_rtsp = new wxCheckBox(this, ID_RTP_OVER_RTSP, wxT("RTP over RTSP"), wxPoint(10, 80), wxSize(140, 20)); - m_reorder = new wxCheckBox(this, -1, wxT("use RTP reordering"), wxPoint(160, 80), wxSize(130, 20)); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(m_rtsp, wxALIGN_CENTER | wxADJUST_MINSIZE); - bs->Add(m_reorder, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - m_timeout = new wxTextCtrl(this, 0, wxT(""), wxPoint(10, 120), wxSize(60, 20)); - bs->Add(new wxStaticText(this, 0, wxT("Control Timeout (ms): ")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - bs->Add(m_timeout, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - m_buffer = new wxTextCtrl(this, 0, wxT(""), wxPoint(10, 150), wxSize(60, 20)); - bs->Add(new wxStaticText(this, 0, wxT("Media Buffering (ms): ")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - bs->Add(m_buffer, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); - bs = new wxBoxSizer(wxHORIZONTAL); - m_dorebuffer = new wxCheckBox(this, ID_RTSP_REBUFFER, wxT("Rebuffer if below")); - bs->Add(m_dorebuffer, wxALIGN_CENTER | wxADJUST_MINSIZE); - m_rebuffer = new wxTextCtrl(this, 0, wxT(""), wxPoint(200, 180), wxSize(60, 20)); - bs->Add(m_rebuffer, wxALIGN_CENTER | wxADJUST_MINSIZE); - m_rebuffer->Disable(); - s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); - s_main->Add(s_stream, 0, wxEXPAND, 0); - - /*streaming cache*/ - s_rec = new wxBoxSizer(wxVERTICAL); - bs = new wxBoxSizer(wxHORIZONTAL); - bs->Add(new wxStaticText(this, 0, wxT("Record To: ")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); - m_recdir = new wxButton(this, ID_RECORD_DIR, wxT("...")); - bs->Add(m_recdir, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rec->Add(bs, 0, wxALL|wxEXPAND, 2); - m_overwrite = new wxCheckBox(this, -1, wxT("Overwrite existing files")); - s_rec->Add(m_overwrite); - bs = new wxBoxSizer(wxHORIZONTAL); - m_usename = new wxCheckBox(this, ID_USE_FILENAME, wxT("Use filename")); - m_recfile = new wxTextCtrl(this, 0, wxT("")); - bs->Add(m_usename, wxALIGN_CENTER | wxADJUST_MINSIZE); - bs->Add(m_recfile, wxALIGN_CENTER | wxADJUST_MINSIZE); - s_rec->Add(bs, 0, wxALL|wxEXPAND, 2); - s_main->Add(s_rec, 0, wxEXPAND, 0); - - /*load options*/ - GF_Config *cfg = m_pApp->m_user.config; - /*general*/ - sOpt = gf_cfg_get_key(cfg, "General", "Loop"); - m_loop->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "General", "LookForSubtitles"); - m_lookforsubs->SetValue((sOpt && !stricmp(sOpt, "no")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "General", "ConsoleOff"); - m_noconsole->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "General", "ViewXMT"); - m_viewxmt->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - - /*systems config*/ - sOpt = gf_cfg_get_key(cfg, "Systems", "Language3CC"); - if (!sOpt) sOpt = "eng"; - u32 select = 0; - i=0; - while (GF_ISO639_Lang[i]) { - /*only use common languages (having both 2- and 3-char code names)*/ - if (GF_ISO639_Lang[i+2][0]) { - m_lang->Append(wxString(GF_ISO639_Lang[i], wxConvUTF8) ); - if (sOpt && !stricmp(sOpt, GF_ISO639_Lang[i+1])) select = m_lang->GetCount() - 1; - } - i+=3; - } - m_lang->SetSelection(select); - sOpt = gf_cfg_get_key(cfg, "Systems", "ThreadingPolicy"); - select = 0; - m_thread->Append(wxT("Single Thread")); - m_thread->Append(wxT("Mutli Thread")); - if (sOpt && !stricmp(sOpt, "Multi")) select = 1; - m_thread->Append(wxT("Free")); - if (sOpt && !stricmp(sOpt, "Free")) select = 2; - m_thread->SetSelection(select); - sOpt = gf_cfg_get_key(cfg, "Systems", "ForceSingleClock"); - m_singletime->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Systems", "AlwaysDrawBIFS"); - m_bifsalwaysdrawn->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - - - /*audio dec enum*/ - sOpt = gf_cfg_get_key(cfg, "Systems", "DefAudioDec"); - u32 count = gf_modules_get_count(m_pApp->m_user.modules); - GF_BaseDecoder *ifc_d; - select = 0; - s32 to_sel = 0; - for (i=0; im_user.modules, i, GF_MEDIA_DECODER_INTERFACE); - if (!ifc_d) continue; - if (ifc_d->CanHandleStream(ifc_d, GF_STREAM_AUDIO, NULL, 0)) { - if (sOpt && !stricmp(ifc_d->module_name, sOpt)) select = to_sel; - m_decaudio->Append(wxString(ifc_d->module_name, wxConvUTF8) ); - to_sel++; - } - gf_modules_close_interface((GF_BaseInterface *) ifc_d); - } - m_decaudio->SetSelection(select); - - /*video dec enum*/ - sOpt = gf_cfg_get_key(cfg, "Systems", "DefVideoDec"); - select = to_sel = 0; - for (i=0; im_user.modules, i, GF_MEDIA_DECODER_INTERFACE); - if (!ifc_d) continue; - if (ifc_d->CanHandleStream(ifc_d, GF_STREAM_VISUAL, NULL, 0)) { - if (sOpt && !stricmp(ifc_d->module_name, sOpt)) select = to_sel; - m_decvideo->Append(wxString(ifc_d->module_name, wxConvUTF8) ); - to_sel++; - } - gf_modules_close_interface((GF_BaseInterface *) ifc_d); - } - m_decvideo->SetSelection(select); - - /*rendering FIXME*/ - m_bWas3D = 0; - m_use3D->SetValue(m_bWas3D ? 1 : 0); - - sOpt = gf_cfg_get_key(cfg, "Compositor", "ForceSceneSize"); - m_force_size->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - - sOpt = gf_cfg_get_key(cfg, "Compositor", "FrameRate"); - if (!sOpt) sOpt = "30.0"; - select = 0; - for (i = 0; iAppend(wxString(BIFSRates[i], wxConvUTF8) ); - if (sOpt && !stricmp(sOpt, BIFSRates[i]) ) select = i; - } - m_fps->SetSelection(select); - - sOpt = gf_cfg_get_key(cfg, "Compositor", "HighSpeed"); - m_fast->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - - sOpt = gf_cfg_get_key(cfg, "Compositor", "AntiAlias"); - m_aa->Append(wxT("None")); - m_aa->Append(wxT("Text only")); - m_aa->Append(wxT("Complete")); - select = 2; - if (sOpt && !stricmp(sOpt, "Text")) select = 1; - else if (sOpt && !stricmp(sOpt, "None")) select = 0; - m_aa->SetSelection(select); - - sOpt = gf_cfg_get_key(cfg, "Compositor", "BoundingVolume"); - m_draw_bounds->Append(wxT("None")); - m_draw_bounds->Append(wxT("Box/Rect")); - m_draw_bounds->Append(wxT("AABB Tree")); - select = 0; - if (sOpt && !stricmp(sOpt, "Box")) select = 1; - else if (sOpt && !stricmp(sOpt, "AABB")) select = 2; - m_draw_bounds->SetSelection(select); - - /*render2d*/ - sOpt = gf_cfg_get_key(cfg, "Compositor", "DirectDraw"); - m_direct->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Compositor", "ScalableZoom"); - m_scalable->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Compositor", "DisableYUV"); - m_noyuv->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - SetYUVLabel(); - - /*graphics driver enum*/ - sOpt = gf_cfg_get_key(cfg, "Compositor", "Raster2D"); - GF_BaseInterface *ifce; - select = to_sel = 0; - for (i=0; im_user.modules, i, GF_RASTER_2D_INTERFACE); - if (!ifce) continue; - if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; - m_graph->Append(wxString(((GF_BaseInterface *)ifce)->module_name, wxConvUTF8) ); - gf_modules_close_interface(ifce); - to_sel++; - } - m_graph->SetSelection(select); - - /*render3d*/ - sOpt = gf_cfg_get_key(cfg, "Compositor", "RasterOutlines"); - m_raster_outlines->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Compositor", "EmulatePOW2"); - m_emulpow2->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Compositor", "PolygonAA"); - m_polyaa->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Compositor", "BackFaceCulling"); - m_nobackcull->SetValue((sOpt && !stricmp(sOpt, "Off")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Compositor", "Wireframe"); - sOpt = gf_cfg_get_key(cfg, "Compositor", "BitmapCopyPixels"); - m_copypixels->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Compositor", "DisableRectExt"); - m_norectext->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - m_wire->Append(wxT("No Wireframe")); - m_wire->Append(wxT("Wireframe Only")); - m_wire->Append(wxT("Solid and Wireframe")); - sOpt = gf_cfg_get_key(cfg, "Compositor", "Wireframe"); - if (sOpt && !stricmp(sOpt, "WireOnly")) m_wire->SetSelection(1); - else if (sOpt && !stricmp(sOpt, "WireOnSolid")) m_wire->SetSelection(2); - else m_wire->SetSelection(0); - m_normals->Append(wxT("Never")); - m_normals->Append(wxT("Per Face")); - m_normals->Append(wxT("Per Vertex")); - sOpt = gf_cfg_get_key(cfg, "Compositor", "DrawNormals"); - if (sOpt && !stricmp(sOpt, "PerFace")) m_normals->SetSelection(1); - else if (sOpt && !stricmp(sOpt, "PerVertex")) m_normals->SetSelection(2); - else m_normals->SetSelection(0); - - /*video*/ - sOpt = gf_cfg_get_key(cfg, "Video", "SwitchResolution"); - m_switchres->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Video", "UseHardwareMemory"); - m_usehwmem->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Video", "DriverName"); - select = to_sel = 0; - for (i=0; im_user.modules, i, GF_VIDEO_OUTPUT_INTERFACE); - if (!ifce) continue; - if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; - m_video->Append(wxString(((GF_BaseInterface *)ifce)->module_name, wxConvUTF8) ); - gf_modules_close_interface(ifce); - to_sel++; - } - m_video->SetSelection(select); - - /*audio*/ - sOpt = gf_cfg_get_key(cfg, "Audio", "ForceConfig"); - m_forcecfg->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Audio", "NumBuffers"); - m_nbbuf->SetValue( sOpt ? wxString(sOpt, wxConvUTF8) : wxT("2")); - sOpt = gf_cfg_get_key(cfg, "Audio", "TotalDuration"); - m_buflen->SetValue( sOpt ? wxString(sOpt, wxConvUTF8) : wxT("120")); - wxCommandEvent event; - ForceAudio(event); - sOpt = gf_cfg_get_key(cfg, "Audio", "NoResync"); - m_noresync->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Audio", "DisableMultiChannel"); - m_nomulitch->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - - /*driver enum*/ - sOpt = gf_cfg_get_key(cfg, "Audio", "DriverName"); - select = to_sel = 0; - for (i=0; im_user.modules, i, GF_AUDIO_OUTPUT_INTERFACE); - if (!ifce) continue; - if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; - m_audio->Append(wxString(((GF_BaseInterface *)ifce)->module_name, wxConvUTF8) ); - gf_modules_close_interface(ifce); - to_sel++; - } - m_audio->SetSelection(select); -#ifdef WIN32 - sOpt = gf_cfg_get_key(cfg, "Audio", "DisableNotification"); - m_notifs->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - wxCommandEvent audevt; - OnSetAudioDriver(audevt); -#endif - - /*font*/ - sOpt = gf_cfg_get_key(cfg, "FontEngine", "FontReader"); - to_sel = select = 0; - for (i=0; im_user.modules, i, GF_FONT_READER_INTERFACE); - if (!ifce) continue; - if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; - m_font->Append(wxString(((GF_BaseInterface *)ifce)->module_name, wxConvUTF8) ); - gf_modules_close_interface(ifce); - to_sel++; - } - m_font->SetSelection(select); - sOpt = gf_cfg_get_key(cfg, "FontEngine", "FontDirectory"); - if (sOpt) m_fontdir->SetLabel(wxString(sOpt, wxConvUTF8) ); - sOpt = gf_cfg_get_key(cfg, "Compositor", "TextureTextMode"); - m_texturemode->Append(wxT("Default")); - m_texturemode->Append(wxT("Never")); - m_texturemode->Append(wxT("Always")); - if (sOpt && !stricmp(sOpt, "Always")) m_texturemode->SetSelection(2); - else if (sOpt && !stricmp(sOpt, "3D")) m_texturemode->SetSelection(1); - else m_texturemode->SetSelection(0); - - /*downloader*/ - sOpt = gf_cfg_get_key(cfg, "General", "CacheDirectory"); - if (sOpt) m_cachedir->SetLabel(wxString(sOpt, wxConvUTF8) ); - sOpt = gf_cfg_get_key(cfg, "Downloader", "CleanCache"); - m_cleancache->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "Downloader", "RestartFiles"); - m_restartcache->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "SAXLoader", "Progressive"); - m_progressive->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(cfg, "SAXLoader", "MaxDuration"); - m_sax_duration->SetValue(sOpt ? wxString(sOpt, wxConvUTF8) : wxT("30")); - if (! m_progressive->GetValue()) m_sax_duration->Enable(0); - - sOpt = gf_cfg_get_key(cfg, "HTTPProxy", "Enabled"); - m_use_proxy->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - char szProxy[GF_MAX_PATH]; - strcpy(szProxy, ""); - sOpt = gf_cfg_get_key(cfg, "HTTPProxy", "Name"); - if (sOpt) { - strcat(szProxy, sOpt); - sOpt = gf_cfg_get_key(cfg, "HTTPProxy", "Port"); - if (sOpt) { - strcat(szProxy, ":"); - strcat(szProxy, sOpt); - } - } else { - m_use_proxy->SetValue(0); - } - m_proxy_name->SetValue( wxString((char *)szProxy, wxConvUTF8) ); - if (! m_use_proxy->GetValue()) m_proxy_name->Enable(0); - - /*streaming*/ - m_port->Append(wxT("554 (RTSP standard)")); - m_port->Append(wxT("7070 (RTSP ext)")); - m_port->Append(wxT("80 (RTSP / HTTP tunnel)")); - m_port->Append(wxT("8080 (RTSP / HTTP tunnel)")); - sOpt = gf_cfg_get_key(cfg, "Streaming", "DefaultPort"); - u32 port = 554; - Bool force_rtsp = 0; - if (sOpt) port = atoi(sOpt); - switch (port) { - case 8080: - m_port->SetSelection(3); - force_rtsp = 1; - break; - case 80: - m_port->SetSelection(2); - force_rtsp = 1; - break; - case 7070: - m_port->SetSelection(1); - break; - default: - m_port->SetSelection(0); - break; - } - - Bool use_rtsp = 0; - sOpt = gf_cfg_get_key(cfg, "Streaming", "RTPoverRTSP"); - if (sOpt && !stricmp(sOpt, "yes")) use_rtsp = 1; - - if (force_rtsp) { - m_rtsp->SetValue(1); - m_rtsp->Enable(0); - m_reorder->SetValue(0); - m_reorder->Enable(0); - } else { - m_rtsp->SetValue(use_rtsp ? 1 : 0); - m_rtsp->Enable(1); - m_reorder->Enable(1); - sOpt = gf_cfg_get_key(cfg, "Streaming", "ReorderSize"); - m_reorder->SetValue( (sOpt && !stricmp(sOpt, "0")) ? 1 : 0); - } - sOpt = gf_cfg_get_key(cfg, "Streaming", "RTSPTimeout"); - m_timeout->SetValue(sOpt ? wxString(sOpt, wxConvUTF8) : wxT("30000")); - sOpt = gf_cfg_get_key(cfg, "Network", "BufferLength"); - m_buffer->SetValue(sOpt ? wxString(sOpt, wxConvUTF8) : wxT("3000")); - sOpt = gf_cfg_get_key(cfg, "Network", "RebufferLength"); - u32 buf_len = 0; - if (sOpt) buf_len = atoi(sOpt); - if (buf_len) { - m_dorebuffer->SetValue(1); - m_rebuffer->SetValue(wxString(sOpt, wxConvUTF8)); - m_rebuffer->Enable(1); - } else { - m_dorebuffer->SetValue(0); - m_rebuffer->SetValue(wxT("0")); - m_rebuffer->Enable(0); - } - - RTPoverRTSP(event); - - sOpt = gf_cfg_get_key(cfg, "StreamingCache", "RecordDirectory"); - if (!sOpt) sOpt = gf_cfg_get_key(cfg, "General", "CacheDirectory"); - if (sOpt) m_recdir->SetLabel(wxString(sOpt, wxConvUTF8)); - sOpt = gf_cfg_get_key(cfg, "StreamingCache", "KeepExistingFiles"); - m_overwrite->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 0 : 1); - - sOpt = gf_cfg_get_key(cfg, "StreamingCache", "BaseFileName"); - if (sOpt) { - m_usename->SetValue(1); - m_recfile->Enable(1); - m_recfile->SetValue(wxString(sOpt, wxConvUTF8)); - } else { - m_usename->SetValue(0); - m_recfile->Enable(0); - m_recfile->SetValue(wxT("uses service URL")); - } - - m_select->Append(wxT("General")); - m_select->Append(wxT("MPEG-4 Systems")); - m_select->Append(wxT("Media Decoders")); - m_select->Append(wxT("Compositor")); - m_select->Append(wxT("Renderer 2D")); - m_select->Append(wxT("Renderer 3D")); - m_select->Append(wxT("Video Output")); - m_select->Append(wxT("Audio Output")); - m_select->Append(wxT("Text Engine")); - m_select->Append(wxT("File Download")); - m_select->Append(wxT("Real-Time Streaming")); - m_select->Append(wxT("Streaming Cache")); - - sOpt = gf_cfg_get_key(cfg, "General", "ConfigPanel"); - m_sel = sOpt ? atoi(sOpt) : 0; - if (m_sel>11) m_sel=11; - m_select->SetSelection(m_sel); - - DoSelect(); -} - -BEGIN_EVENT_TABLE(wxGPACControl, wxDialog) - EVT_BUTTON(ID_APPLY, wxGPACControl::Apply) - EVT_COMBOBOX(ID_SELECT, wxGPACControl::OnSetSelection) - EVT_CHECKBOX(ID_FORCE_AUDIO, wxGPACControl::ForceAudio) - EVT_COMBOBOX(ID_AUDIO_DRIVER, wxGPACControl::OnSetAudioDriver) - EVT_BUTTON(ID_FONT_DIR, wxGPACControl::FontDir) - EVT_BUTTON(ID_CACHE_DIR, wxGPACControl::CacheDir) - EVT_CHECKBOX(ID_PROGRESSIVE, wxGPACControl::OnProgressive) - EVT_CHECKBOX(ID_USE_PROXY, wxGPACControl::OnUseProxy) - EVT_CHECKBOX(ID_RTP_OVER_RTSP, wxGPACControl::RTPoverRTSP) - EVT_CHECKBOX(ID_RTSP_REBUFFER, wxGPACControl::Rebuffer) - EVT_COMBOBOX(ID_RTSP_PORT, wxGPACControl::OnSetRTSPPort) - EVT_CHECKBOX(ID_USE_FILENAME, wxGPACControl::OnUseFileName) - EVT_BUTTON(ID_RECORD_DIR, wxGPACControl::OnRecDir) -END_EVENT_TABLE() - - -wxGPACControl::~wxGPACControl() -{ - char str[20]; - sprintf(str, "%d", m_sel); - gf_cfg_set_key(m_pApp->m_user.config, "General", "ConfigPanel", str); -} - - -void wxGPACControl::DoSelect() -{ - - /*hide everything*/ - s_main->Show(s_general, false); - s_main->Show(s_mpeg4, false); - s_main->Show(s_mdec, false); - s_main->Show(s_rend, false); - s_main->Show(s_rend2d, false); - s_main->Show(s_rend3d, false); - s_main->Show(s_video, false); - s_main->Show(s_audio, false); - s_main->Show(s_font, false); - s_main->Show(s_dnld, false); - s_main->Show(s_stream, false); - s_main->Show(s_rec, false); - switch (m_sel) { - case 0: s_main->Show(s_general, true); break; - case 1: s_main->Show(s_mpeg4, true); break; - case 2: s_main->Show(s_mdec, true); break; - case 3: s_main->Show(s_rend, true); break; - case 4: s_main->Show(s_rend2d, true); break; - case 5: s_main->Show(s_rend3d, true); break; - case 6: s_main->Show(s_video, true); break; - case 7: s_main->Show(s_audio, true); break; - case 8: s_main->Show(s_font, true); break; - case 9: s_main->Show(s_dnld, true); break; - case 10: s_main->Show(s_stream, true); break; - case 11: s_main->Show(s_rec, true); break; - } - SetSizer(s_main); - s_main->Fit(this); - //s_main->Layout(); - return; - -} - -void wxGPACControl::OnSetSelection(wxCommandEvent &WXUNUSED(event)) -{ - m_sel = m_select->GetSelection(); - DoSelect(); -} - -void wxGPACControl::FontDir(wxCommandEvent &WXUNUSED(event)) -{ - wxDirDialog dlg(this); - dlg.SetPath(m_fontdir->GetLabel()); - if (dlg.ShowModal() == wxID_OK) { - m_fontdir->SetLabel(dlg.GetPath()); - } -} -void wxGPACControl::CacheDir(wxCommandEvent &WXUNUSED(event)) -{ - wxDirDialog dlg(this); - dlg.SetPath(m_cachedir->GetLabel()); - if (dlg.ShowModal() == wxID_OK) { - m_cachedir->SetLabel(dlg.GetPath()); - } -} - -void wxGPACControl::OnProgressive(wxCommandEvent &WXUNUSED(event)) -{ - m_sax_duration->Enable(m_progressive->GetValue() ? 1 : 0); -} - -void wxGPACControl::OnUseProxy(wxCommandEvent &WXUNUSED(event)) -{ - m_proxy_name->Enable(m_use_proxy->GetValue() ? 1 : 0); -} - -void wxGPACControl::RTPoverRTSP(wxCommandEvent &WXUNUSED(event)) -{ - m_reorder->Enable(m_rtsp->GetValue() ? 0 : 1); -} - -void wxGPACControl::Rebuffer(wxCommandEvent &WXUNUSED(event)) -{ - if (m_dorebuffer->GetValue()) { - m_rebuffer->Enable(); - } else { - m_rebuffer->Disable(); - } -} - -void wxGPACControl::OnSetRTSPPort(wxCommandEvent &WXUNUSED(event)) -{ - if (m_port->GetSelection() > 1) { - m_rtsp->Enable(0); - m_reorder->Enable(0); - } else { - m_rtsp->Enable(1); - m_reorder->Enable(1); - } -} - -void wxGPACControl::OnRecDir(wxCommandEvent &WXUNUSED(event)) -{ - wxDirDialog dlg(this); - dlg.SetPath(m_recdir->GetLabel()); - if (dlg.ShowModal() == wxID_OK) { - m_recdir->SetLabel(dlg.GetPath()); - } -} - -void wxGPACControl::OnUseFileName(wxCommandEvent &WXUNUSED(event)) -{ - if (m_usename->GetValue()) { - m_recfile->Enable(); - m_recfile->SetValue(wxT("record")); - } else { - m_recfile->Disable(); - m_recfile->SetValue(wxT("uses service URL")); - } -} - -void wxGPACControl::ForceAudio(wxCommandEvent &WXUNUSED(event)) -{ - if (m_forcecfg->GetValue()) { - m_nbbuf->Enable(); - m_buflen->Enable(); - } else { - m_nbbuf->Disable(); - m_buflen->Disable(); - } -} - -void wxGPACControl::OnSetAudioDriver(wxCommandEvent &WXUNUSED(event)) -{ -#ifdef WIN32 - if (strstr(m_audio->GetStringSelection().mb_str(wxConvUTF8), "DirectSound")) { - m_notifs->Enable(1); - } else { - m_notifs->Enable(0); - } -#endif -} - - - -void wxGPACControl::Apply(wxCommandEvent &WXUNUSED(event)) -{ - /*save options*/ - GF_Config *cfg = m_pApp->m_user.config; - - m_pApp->m_loop = m_loop->GetValue() ? 1 : 0; - gf_cfg_set_key(cfg, "General", "Loop", m_loop->GetValue() ? "yes" : "no"); - m_pApp->m_lookforsubs = m_lookforsubs->GetValue() ? 1 : 0; - gf_cfg_set_key(cfg, "General", "LookForSubtitles", m_lookforsubs->GetValue() ? "yes" : "no"); - m_pApp->m_console_off = m_noconsole->GetValue() ? 1 : 0; - gf_cfg_set_key(cfg, "General", "ConsoleOff", m_noconsole->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "General", "ViewXMT", m_viewxmt->GetValue() ? "yes" : "no"); - - s32 sel = m_lang->GetSelection(); - u32 i=0; - while (GF_ISO639_Lang[i]) { - /*only use common languages (having both 2- and 3-char code names)*/ - if (GF_ISO639_Lang[i+2][0]) { - if (!sel) break; - sel--; - } - i+=3; - } - gf_cfg_set_key(cfg, "Systems", "LanguageName", GF_ISO639_Lang[i]); - gf_cfg_set_key(cfg, "Systems", "Language3CC", GF_ISO639_Lang[i+1]); - gf_cfg_set_key(cfg, "Systems", "Language2CC", GF_ISO639_Lang[i+2]); - - - sel = m_thread->GetSelection(); - gf_cfg_set_key(cfg, "Systems", "ThreadingPolicy", (sel==0) ? "Single" : ( (sel==1) ? "Multi" : "Free")); - gf_cfg_set_key(cfg, "Systems", "ForceSingleClock", m_singletime->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Systems", "AlwaysDrawBIFS", m_bifsalwaysdrawn->GetValue() ? "yes" : "no"); - - gf_cfg_set_key(cfg, "Systems", "DefAudioDec", m_decaudio->GetStringSelection().mb_str(wxConvUTF8)); - gf_cfg_set_key(cfg, "Systems", "DefVideoDec", m_decvideo->GetStringSelection().mb_str(wxConvUTF8)); - - - gf_cfg_set_key(cfg, "Compositor", "HighSpeed", m_fast->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Compositor", "ForceSceneSize", m_force_size->GetValue() ? "yes" : "no"); - - gf_cfg_set_key(cfg, "Compositor", "FrameRate", BIFSRates[m_fps->GetSelection()]); - sel = m_aa->GetSelection(); - gf_cfg_set_key(cfg, "Compositor", "AntiAlias", (sel==0) ? "None" : ( (sel==1) ? "Text" : "All")); - sel = m_draw_bounds->GetSelection(); - gf_cfg_set_key(cfg, "Compositor", "BoundingVolume", (sel==2) ? "AABB" : (sel==1) ? "Box" : "None"); - - Bool is_3D = m_use3D->GetValue() ? 1 : 0; - if (m_bWas3D != is_3D) { - /*FIXME*/ - } - gf_cfg_set_key(cfg, "Compositor", "Raster2D", m_graph->GetStringSelection().mb_str(wxConvUTF8)); - - gf_cfg_set_key(cfg, "Compositor", "DirectDraw", m_direct->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", m_scalable->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Compositor", "DisableYUV", m_noyuv->GetValue() ? "yes" : "no"); - - gf_cfg_set_key(cfg, "Compositor", "RasterOutlines", m_raster_outlines->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Compositor", "EmulatePOW2", m_emulpow2->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Compositor", "PolygonAA", m_polyaa->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Compositor", "DisableRectExt", m_norectext->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Compositor", "BitmapCopyPixels", m_copypixels->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Compositor", "BackFaceCulling", m_nobackcull->GetValue() ? "Off" : "On"); - - sel = m_wire->GetSelection(); - gf_cfg_set_key(cfg, "Compositor", "Wireframe", (sel==2) ? "WireOnSolid" : ( (sel==1) ? "WireOnly" : "WireNone" ) ); - sel = m_normals->GetSelection(); - gf_cfg_set_key(cfg, "Compositor", "DrawNormals", (sel==2) ? "PerVertex" : ( (sel==1) ? "PerFace" : "Never" ) ); - - gf_cfg_set_key(cfg, "Video", "SwitchResolution", m_switchres->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Video", "UseHardwareMemory", m_usehwmem->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Video", "DriverName", m_video->GetStringSelection().mb_str(wxConvUTF8)); - - - gf_cfg_set_key(cfg, "Audio", "ForceConfig", m_forcecfg->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Audio", "NoResync", m_noresync->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Audio", "DisableMultiChannel", m_nomulitch->GetValue() ? "yes" : "no"); - - gf_cfg_set_key(cfg, "Audio", "NumBuffers", wxString::Format(wxT("%d"), m_nbbuf->GetValue()).mb_str(wxConvUTF8) ); - gf_cfg_set_key(cfg, "Audio", "TotalDuration", wxString::Format(wxT("%d"), m_buflen->GetValue()).mb_str(wxConvUTF8) ); - gf_cfg_set_key(cfg, "Audio", "DriverName", m_audio->GetStringSelection().mb_str(wxConvUTF8)); -#ifdef WIN32 - if (m_notifs->IsEnabled()) - gf_cfg_set_key(cfg, "Audio", "DisableNotification", m_notifs->GetValue() ? "yes" : "no"); -#endif - - gf_cfg_set_key(cfg, "FontEngine", "FontReader", m_font->GetStringSelection().mb_str(wxConvUTF8)); - gf_cfg_set_key(cfg, "FontEngine", "FontDirectory", m_fontdir->GetLabel().mb_str(wxConvUTF8)); - switch (m_texturemode->GetSelection()) { - case 2: gf_cfg_set_key(cfg, "Compositor", "TextureTextMode", "Always"); break; - case 1: gf_cfg_set_key(cfg, "Compositor", "TextureTextMode", "Never"); break; - default: gf_cfg_set_key(cfg, "Compositor", "TextureTextMode", "Default"); break; - } - - gf_cfg_set_key(cfg, "Downloader", "CleanCache", m_cleancache->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "Downloader", "RestartFiles", m_restartcache->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "SAXLoader", "Progressive", m_progressive->GetValue() ? "yes" : "no"); - gf_cfg_set_key(cfg, "SAXLoader", "MaxDuration", m_sax_duration->GetLabel().mb_str(wxConvUTF8)); - gf_cfg_set_key(cfg, "General", "CacheDirectory", m_cachedir->GetLabel().mb_str(wxConvUTF8)); - - - Bool force_rtsp = 0; - switch (m_port->GetSelection()) { - case 3: - gf_cfg_set_key(cfg, "Streaming", "DefaultPort", "8080"); - force_rtsp = 1; - break; - case 2: - gf_cfg_set_key(cfg, "Streaming", "DefaultPort", "80"); - force_rtsp = 1; - break; - case 1: - gf_cfg_set_key(cfg, "Streaming", "DefaultPort", "7070"); - break; - default: - gf_cfg_set_key(cfg, "Streaming", "DefaultPort", "554"); - break; - } - - if (force_rtsp) { - gf_cfg_set_key(cfg, "Streaming", "RTPoverRTSP", "yes"); - } else { - gf_cfg_set_key(cfg, "Streaming", "RTPoverRTSP", m_rtsp->GetValue() ? "yes" : "no"); - if (!m_rtsp->GetValue()) gf_cfg_set_key(cfg, "Streaming", "ReorderSize", m_dorebuffer->GetValue() ? "30" : "0"); - } - - gf_cfg_set_key(cfg, "Streaming", "RTSPTimeout", m_timeout->GetValue().mb_str(wxConvUTF8)); - gf_cfg_set_key(cfg, "Network", "BufferLength", m_buffer->GetValue().mb_str(wxConvUTF8)); - if (m_dorebuffer->GetValue()) { - gf_cfg_set_key(cfg, "Network", "RebufferLength", m_rebuffer->GetValue().mb_str(wxConvUTF8)); - } else { - gf_cfg_set_key(cfg, "Network", "RebufferLength", "0"); - } - - gf_cfg_set_key(cfg, "StreamingCache", "KeepExistingFiles", m_overwrite->GetValue() ? "no" : "yes"); - if (m_usename->GetValue()) { - gf_cfg_set_key(cfg, "StreamingCache", "BaseFileName", m_recfile->GetValue().mb_str(wxConvUTF8)); - } else { - gf_cfg_set_key(cfg, "StreamingCache", "BaseFileName", NULL); - } - gf_cfg_set_key(cfg, "StreamingCache", "RecordDirectory", m_recdir->GetLabel().mb_str(wxConvUTF8)); - - - gf_term_set_option(m_pApp->m_term, GF_OPT_RELOAD_CONFIG, 1); -} - diff --git a/applications/osmo4_wx/wxGPACControl.h b/applications/osmo4_wx/wxGPACControl.h deleted file mode 100644 index 043d902..0000000 --- a/applications/osmo4_wx/wxGPACControl.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Osmo4 wxWidgets GUI - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#ifndef _OPTIONS_H -#define _OPTIONS_H - -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include -#include - -enum -{ - ID_SELECT = 1000, - ID_APPLY, - - ID_MAKE_DEF, - ID_FORCE_AUDIO, - ID_AUDIO_DRIVER, - ID_FONT_DIR, - ID_CACHE_DIR, - ID_PROGRESSIVE, - ID_RTSP_PORT, - ID_RTP_OVER_RTSP, - ID_RTSP_REBUFFER, - ID_RECORD_DIR, - ID_USE_FILENAME, - ID_USE_PROXY, -}; - -class wxOsmo4Frame; -class wxGPACControl : public wxDialog -{ -public: - wxGPACControl(wxWindow *parent); - virtual ~wxGPACControl(); - -private: - DECLARE_EVENT_TABLE() - - wxOsmo4Frame *m_pApp; - - wxComboBox *m_select; - Bool m_bWas3D; - - void Apply(wxCommandEvent &event); - void OnSetSelection(wxCommandEvent &event); - void ForceAudio(wxCommandEvent &event); - void OnSetAudioDriver(wxCommandEvent &event); - void FontDir(wxCommandEvent &event); - void CacheDir(wxCommandEvent &event); - void OnProgressive(wxCommandEvent &event); - void OnUseProxy(wxCommandEvent &event); - void RTPoverRTSP(wxCommandEvent &event); - void Rebuffer(wxCommandEvent &event); - void OnSetRTSPPort(wxCommandEvent &event); - void OnUseFileName(wxCommandEvent &event); - void OnRecDir(wxCommandEvent &event); - void DoSelect(); - s32 m_sel; - void SetYUVLabel(); - - wxBoxSizer *s_header, *s_main, *s_general, *s_mpeg4, *s_mdec, *s_rend, *s_rend2d, *s_rend3d, *s_audio, *s_video, *s_font, *s_dnld, *s_stream, *s_rec; - - /*general section*/ - wxCheckBox *m_loop, *m_lookforsubs, *m_noconsole, *m_viewxmt; - /*MPEG-4 systems*/ - wxCheckBox *m_bifsalwaysdrawn, *m_singletime; - wxComboBox *m_lang, *m_thread; - /*media decoders*/ - wxComboBox *m_decaudio, *m_decvideo; - /*Rendering*/ - wxComboBox *m_fps, *m_aa, *m_draw_bounds; - wxCheckBox *m_use3D, *m_fast, *m_force_size; - /*Renderer 2D*/ - wxComboBox *m_graph; - wxCheckBox *m_noyuv, *m_direct, *m_scalable; - wxStaticText *m_yuvtxt; - /*Renderer 3D*/ - wxCheckBox *m_raster_outlines, *m_polyaa, *m_nobackcull, *m_emulpow2, *m_norectext, *m_copypixels; - wxComboBox *m_wire, *m_normals; - /*video*/ - wxComboBox *m_video; - wxCheckBox *m_switchres, *m_usehwmem; - /*audio*/ - wxSpinCtrl *m_nbbuf, *m_buflen; - wxComboBox *m_audio; - wxCheckBox *m_forcecfg, *m_noresync, *m_nomulitch; -#ifdef WIN32 - wxCheckBox *m_notifs; -#endif - /*font*/ - wxComboBox *m_font; - wxButton *m_fontdir; - wxComboBox *m_texturemode; - /*file download*/ - wxButton *m_cachedir; - wxCheckBox *m_cleancache, *m_restartcache, *m_progressive, *m_use_proxy; - wxTextCtrl *m_sax_duration, *m_proxy_name; - /*streaming*/ - wxComboBox *m_port; - wxCheckBox *m_rtsp, *m_reorder, *m_dorebuffer; - wxTextCtrl *m_timeout, *m_buffer, *m_rebuffer; - /*file recorder*/ - wxButton *m_recdir; - wxCheckBox *m_overwrite, *m_usename; - wxTextCtrl *m_recfile; -}; - -#endif - diff --git a/applications/osmo4_wx/wxOsmo4.cpp b/applications/osmo4_wx/wxOsmo4.cpp deleted file mode 100644 index b25b199..0000000 --- a/applications/osmo4_wx/wxOsmo4.cpp +++ /dev/null @@ -1,2347 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Osmo4 wxWidgets GUI - * - * GPAC is gf_free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - - -#include "wxOsmo4.h" -#include "wxGPACControl.h" -#include "fileprops.h" -#include -#include -#include -#include -#include - - -IMPLEMENT_APP(wxOsmo4App) - -#include "osmo4.xpm" - -#include - - - - - -#include -#include - -#include "toolbar.xpm" - -#include "Playlist.h" - -#ifdef WIN32 -#define FRAME_H 140 -#else -#define FRAME_H 110 -#endif - - -wxString get_pref_browser(GF_Config *cfg) -{ - const char *sOpt = gf_cfg_get_key(cfg, "General", "Browser"); - if (sOpt) return wxString(sOpt, wxConvUTF8); - return wxEmptyString; -/* -#ifdef __WXMAC__ - return wxT("safari"); -#else -#ifdef WIN32 - return wxT("explorer.exe"); -#else - return wxT("mozilla"); -#endif -#endif*/ -} - - -IMPLEMENT_DYNAMIC_CLASS(wxGPACEvent, wxEvent ) - -wxGPACEvent::wxGPACEvent(wxWindow* win) -{ - SetEventType(GPAC_EVENT); - SetEventObject(win); - gpac_evt.type = 0; - to_url = wxT(""); -} -wxEvent *wxGPACEvent::Clone() const -{ - wxGPACEvent *evt = new wxGPACEvent((wxWindow *) m_eventObject); - evt->to_url = to_url; - evt->gpac_evt = gpac_evt; - return evt; -} - -#include - -/*open file dlg*/ -BEGIN_EVENT_TABLE(OpenURLDlg, wxDialog) - EVT_BUTTON(ID_URL_GO, OpenURLDlg::OnGo) -END_EVENT_TABLE() - -OpenURLDlg::OpenURLDlg(wxWindow *parent, GF_Config *cfg) - : wxDialog(parent, -1, wxString(wxT("Enter remote presentation location"))) -{ -#ifndef WIN32 - SetSize(430, 35); -#else - SetSize(430, 55); -#endif - Centre(); - m_url = new wxComboBox(this, -1, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN); - m_url->SetSize(0, 2, 340, 18, wxSIZE_AUTO); - m_go = new wxButton(this, ID_URL_GO, wxT("Go !")); -#ifndef WIN32 - m_go->SetSize(344, 2, 20, 18, wxSIZE_AUTO); -#else - m_go->SetSize(364, 2, 30, 18, wxSIZE_AUTO); -#endif - m_urlVal = wxT(""); - - m_cfg = cfg; - - const char *sOpt; - u32 i=0; - - while (1) { - sOpt = gf_cfg_get_key_name(m_cfg, "RecentFiles", i); - if (!sOpt) break; - m_url->Append(wxString(sOpt, wxConvUTF8) ); - i++; - } -} - -#define MAX_LAST_FILES 20 -void UpdateLastFiles(GF_Config *cfg, const char *URL) -{ - u32 nb_entries; - gf_cfg_set_key(cfg, "RecentFiles", URL, NULL); - gf_cfg_insert_key(cfg, "RecentFiles", URL, "", 0); - /*remove last entry if needed*/ - nb_entries = gf_cfg_get_key_count(cfg, "RecentFiles"); - if (nb_entries>MAX_LAST_FILES) { - gf_cfg_set_key(cfg, "RecentFiles", gf_cfg_get_key_name(cfg, "RecentFiles", nb_entries-1), NULL); - } -} - -void OpenURLDlg::OnGo(wxCommandEvent& event) -{ - m_urlVal = m_url->GetValue(); - UpdateLastFiles(m_cfg, m_urlVal.mb_str(wxConvUTF8)); - EndModal(wxID_OK); -} -/*end open file dlg*/ - -#ifdef WIN32 -u32 get_sys_col(int idx) -{ - u32 res; - DWORD val = GetSysColor(idx); - res = (val)&0xFF; res<<=8; - res |= (val>>8)&0xFF; res<<=8; - res |= (val>>16)&0xFF; - return res; -} -#endif - -static void wxOsmo4_progress_cbk(const void *usr, const char *title, u64 done, u64 total) -{ - if (!total) return; - wxOsmo4Frame *app = (wxOsmo4Frame *)usr; - s32 prog = (s32) ( (100 * (u64)done) / total); - if (app->m_last_prog < prog) { - app->m_last_prog = prog; - - if (prog<100) { - /*appears to crash wxWidgets / X11 when refreshing the text too often*/ - if (app->m_LastStatusTime + 200 > gf_sys_clock()) return; - char msg[1024]; - sprintf(msg, "%s %02d %%)", title, prog); - //app->SetStatus(wxString(msg, wxConvUTF8)); - } else { - app->SetStatus(wxT("Ready")); - app->m_last_prog = -1; - } - } -} - -Bool GPAC_EventProc(void *ptr, GF_Event *evt) -{ - wxCommandEvent event; - wxOsmo4Frame *app = (wxOsmo4Frame *)ptr; - - switch (evt->type) { - case GF_EVENT_DURATION: - app->m_duration = (u32) (evt->duration.duration*1000); - app->m_can_seek = evt->duration.can_seek; - if (app->m_duration<1100) app->m_can_seek = 0; - app->m_pProg->Enable(app->m_can_seek ? 1 : 0); - app->m_pPlayList->SetDuration((u32) evt->duration.duration); - break; - case GF_EVENT_MESSAGE: - { - const char *servName; - if (!evt->message.service || !strcmp(evt->message.service, app->m_pPlayList->GetURL().mb_str(wxConvUTF8))) { - servName = "main service"; - } else { - servName = evt->message.service; - } - if (!evt->message.message) return 0; - - if (evt->message.error) { - app->SetStatus(wxString(evt->message.message, wxConvUTF8) + wxT(" (") + wxString(servName, wxConvUTF8) + wxT(")") ); - if (!app->m_connected) app->m_pPlayList->SetDead(); - } - else if (!app->m_console_off) { - if (strstr(evt->message.message, "100 %")) { - app->SetStatus(wxT("")); - } else { - app->SetStatus(wxString(evt->message.message, wxConvUTF8) ); - } - } - -#if 0 - /*log*/ - if (evt->message.error) - ::wxLogMessage(wxString(evt->message.message, wxConvUTF8) + wxT(" (") + wxString(servName, wxConvUTF8) + wxT(") ") + wxString(gf_error_to_string(evt->message.error), wxConvUTF8) ); - else - ::wxLogMessage(wxString(evt->message.message, wxConvUTF8) + wxT(" (") + wxString(servName, wxConvUTF8) + wxT(")")); -#endif - } - break; - case GF_EVENT_PROGRESS: - { - const char *sTitle; - if (evt->progress.progress_type==0) sTitle = (char *)"Buffer"; - else if (evt->progress.progress_type==1) sTitle = (char *)"Download"; - else if (evt->progress.progress_type==2) sTitle = (char *)"Import"; - gf_set_progress(sTitle, evt->progress.done, evt->progress.total); - } - break; - case GF_EVENT_KEYDOWN: - if (app->m_can_seek && (evt->key.flags & GF_KEY_MOD_ALT)) { - s32 res; - switch (evt->key.key_code) { - case GF_KEY_LEFT: - res = gf_term_get_time_in_ms(app->m_term) - 5*app->m_duration/100; - if (res<0) res=0; - gf_term_play_from_time(app->m_term, res, 0); - break; - case GF_KEY_RIGHT: - res = gf_term_get_time_in_ms(app->m_term) + 5*app->m_duration/100; - if ((u32) res>=app->m_duration) res = 0; - gf_term_play_from_time(app->m_term, res, 0); - break; - case GF_KEY_DOWN: - res = gf_term_get_time_in_ms(app->m_term) - 60000; - if (res<0) res=0; - gf_term_play_from_time(app->m_term, res, 0); - break; - case GF_KEY_UP: - res = gf_term_get_time_in_ms(app->m_term) + 60000; - if ((u32) res>=app->m_duration) res = 0; - gf_term_play_from_time(app->m_term, res, 0); - break; - } - } else if (evt->key.flags & GF_KEY_MOD_CTRL) { - switch (evt->key.key_code) { - case GF_KEY_LEFT: - app->m_pPlayList->PlayPrev(); - break; - case GF_KEY_RIGHT: - app->m_pPlayList->PlayNext(); - break; - } - } else { - switch (evt->key.key_code) { - case GF_KEY_HOME: - gf_term_set_option(app->m_term, GF_OPT_NAVIGATION_TYPE, 1); - break; - case GF_KEY_ESCAPE: - if (gf_term_get_option(app->m_term, GF_OPT_FULLSCREEN)) - gf_term_set_option(app->m_term, GF_OPT_FULLSCREEN, 0); - break; - default: - { - wxGPACEvent wxevt(app); - wxevt.gpac_evt = *evt; - app->AddPendingEvent(wxevt); - } - break; - } - } - break; - - case GF_EVENT_CONNECT: - { - wxGPACEvent wxevt(app); - wxevt.gpac_evt.type = GF_EVENT_CONNECT; - wxevt.gpac_evt.connect.is_connected = evt->connect.is_connected; - if (!evt->connect.is_connected) app->m_duration = 0; - app->AddPendingEvent(wxevt); - } - break; - case GF_EVENT_NAVIGATE: - { - wxGPACEvent wxevt(app); - wxevt.to_url = wxString(evt->navigate.to_url, wxConvUTF8); - wxevt.gpac_evt.type = evt->type; - app->AddPendingEvent(wxevt); - } - return 1; - case GF_EVENT_SET_CAPTION: - { - wxGPACEvent wxevt(app); - wxevt.to_url = wxString(evt->caption.caption, wxConvUTF8); - wxevt.gpac_evt.type = evt->type; - app->AddPendingEvent(wxevt); - } - return 1; - - case GF_EVENT_QUIT: - case GF_EVENT_VIEWPOINTS: - case GF_EVENT_STREAMLIST: - case GF_EVENT_SCENE_SIZE: -// case GF_EVENT_SIZE: - { - wxGPACEvent wxevt(app); - wxevt.gpac_evt = *evt; - app->AddPendingEvent(wxevt); - } - break; - case GF_EVENT_DBLCLICK: - gf_term_set_option(app->m_term, GF_OPT_FULLSCREEN, !gf_term_get_option(app->m_term, GF_OPT_FULLSCREEN)); - return 0; - case GF_EVENT_MOUSEDOWN: - if (!gf_term_get_option(app->m_term, GF_OPT_FULLSCREEN)) { -#ifdef __WXGTK__ - app->m_pVisual->SetFocus(); -#else - app->m_pView->SetFocus(); -#endif - } - break; - case GF_EVENT_AUTHORIZATION: - { - wxGPACEvent wxevt(app); - wxTextEntryDialog user_d (0, - wxT("Please set the user name for connection"), - wxString(evt->auth.site_url, wxConvUTF8), - wxString(evt->auth.user, wxConvUTF8)); - if (user_d.ShowModal() != wxID_OK) - return 0; - strncpy(evt->auth.user, user_d.GetValue().mb_str(wxConvUTF8), 50); - wxPasswordEntryDialog passwd_d(0, - wxT("Please enter password"), - wxString(evt->auth.site_url, wxConvUTF8), - wxString(evt->auth.password, wxConvUTF8)); - if (passwd_d.ShowModal() != wxID_OK) - return 0; - strncpy(evt->auth.password, passwd_d.GetValue().mb_str(wxConvUTF8), 50); - return 1; - } - case GF_EVENT_SYS_COLORS: -#ifdef WIN32 - evt->sys_cols.sys_colors[0] = get_sys_col(COLOR_ACTIVEBORDER); - evt->sys_cols.sys_colors[1] = get_sys_col(COLOR_ACTIVECAPTION); - evt->sys_cols.sys_colors[2] = get_sys_col(COLOR_APPWORKSPACE); - evt->sys_cols.sys_colors[3] = get_sys_col(COLOR_BACKGROUND); - evt->sys_cols.sys_colors[4] = get_sys_col(COLOR_BTNFACE); - evt->sys_cols.sys_colors[5] = get_sys_col(COLOR_BTNHIGHLIGHT); - evt->sys_cols.sys_colors[6] = get_sys_col(COLOR_BTNSHADOW); - evt->sys_cols.sys_colors[7] = get_sys_col(COLOR_BTNTEXT); - evt->sys_cols.sys_colors[8] = get_sys_col(COLOR_CAPTIONTEXT); - evt->sys_cols.sys_colors[9] = get_sys_col(COLOR_GRAYTEXT); - evt->sys_cols.sys_colors[10] = get_sys_col(COLOR_HIGHLIGHT); - evt->sys_cols.sys_colors[11] = get_sys_col(COLOR_HIGHLIGHTTEXT); - evt->sys_cols.sys_colors[12] = get_sys_col(COLOR_INACTIVEBORDER); - evt->sys_cols.sys_colors[13] = get_sys_col(COLOR_INACTIVECAPTION); - evt->sys_cols.sys_colors[14] = get_sys_col(COLOR_INACTIVECAPTIONTEXT); - evt->sys_cols.sys_colors[15] = get_sys_col(COLOR_INFOBK); - evt->sys_cols.sys_colors[16] = get_sys_col(COLOR_INFOTEXT); - evt->sys_cols.sys_colors[17] = get_sys_col(COLOR_MENU); - evt->sys_cols.sys_colors[18] = get_sys_col(COLOR_MENUTEXT); - evt->sys_cols.sys_colors[19] = get_sys_col(COLOR_SCROLLBAR); - evt->sys_cols.sys_colors[20] = get_sys_col(COLOR_3DDKSHADOW); - evt->sys_cols.sys_colors[21] = get_sys_col(COLOR_3DFACE); - evt->sys_cols.sys_colors[22] = get_sys_col(COLOR_3DHIGHLIGHT); - evt->sys_cols.sys_colors[23] = get_sys_col(COLOR_3DLIGHT); - evt->sys_cols.sys_colors[24] = get_sys_col(COLOR_3DSHADOW); - evt->sys_cols.sys_colors[25] = get_sys_col(COLOR_WINDOW); - evt->sys_cols.sys_colors[26] = get_sys_col(COLOR_WINDOWFRAME); - evt->sys_cols.sys_colors[27] = get_sys_col(COLOR_WINDOWTEXT); - return 1; -#else - memset(evt->sys_cols.sys_colors, 0, sizeof(u32)*28); - return 1; -#endif - } - return 0; -} - - - -bool wxOsmo4App::OnInit() -{ -#ifdef __WXGTK__ - XSynchronize((Display *) wxGetDisplay(), 1); -#endif - wxFrame *frame = new wxOsmo4Frame(); - frame->Show(TRUE); - SetTopWindow(frame); - return true; -} - - -class myDropfiles : public wxFileDropTarget -{ -public: - myDropfiles() : wxFileDropTarget() {} - virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames); - wxOsmo4Frame *m_pMain; -}; - -bool myDropfiles::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames) -{ - u32 count = filenames.GetCount(); - - if (count==1) { - const char *ext = strrchr(filenames.Item(0).mb_str(wxConvUTF8) , '.'); - /*if playing and sub d&d, open sub in current presentation*/ - if (m_pMain->m_connected && ext && ( !stricmp(ext, ".srt") || !stricmp(ext, ".sub") || !stricmp(ext, ".ttxt") || !stricmp(ext, ".xml") ) ) { - m_pMain->AddSubtitle(filenames.Item(0).mb_str(wxConvUTF8) , 1); - return TRUE; - } - } - - for (u32 i=0; im_pPlayList->QueueURL(filenames.Item(i)); - - m_pMain->m_pPlayList->RefreshList(); - m_pMain->m_pPlayList->PlayNext(); - return TRUE; -} - -bool GPACLogs::OnFrameClose(wxFrame *frame) -{ - Show(FALSE); - return 0; -} - -void wxOsmo4Frame::ShowViewWindow(Bool do_show) -{ - m_pView->Show(do_show ? 1 : 0); -#ifdef __WXGTK__ - //m_pView->Show(0); -#endif -} - -#ifdef __WXGTK__ -extern "C" { -#ifdef __WXGTK20__ - int gdk_x11_drawable_get_xid( void * ); - void *gdk_x11_drawable_get_xdisplay( void * ); -#endif - void *gtk_widget_get_parent_window( void * ); -} -#endif - - -void wxOsmo4Frame::CheckVideoOut() -{ - const char *sOpt = gf_cfg_get_key(m_user.config, "Video", "DriverName"); - void *os_handle = NULL; - void *os_display = NULL; - /*build a child window for embed display*/ - if (sOpt && stricmp(sOpt, "SDL Video Output")) { - if (m_user.os_window_handler) return; - m_bExternalView = 0; - -#ifdef __WXGTK__ - GtkWidget* widget = m_pVisual->GetHandle(); - -#ifdef __WXGTK20__ - os_handle = (void *) gdk_x11_drawable_get_xid(gtk_widget_get_parent_window(widget)); -#else - os_handle = (void *)*(int *)( (char *)gtk_widget_get_parent_window(widget) + 2 * sizeof(void *) ); -#endif - -#elif defined (WIN32) - os_handle = m_pView->GetHandle(); -#endif - if (os_handle) { - m_user.os_window_handler = os_handle; - m_user.os_display = os_display; - ShowViewWindow(1); - m_pView->SetSize(320, 240); - SetSize(wxSize(320, 240+FRAME_H)); - SetWindowStyle(wxDEFAULT_FRAME_STYLE); - DoLayout(320, 240); - return; - } - } - /*we're using SDL, don't use SDL hack*/ - m_bExternalView = 1; - m_user.os_window_handler = 0; - m_user.os_display = NULL; - SetSize(wxSize(320,FRAME_H)); - m_pView->SetSize(0, 0); - ShowViewWindow(0); - DoLayout(); - SetWindowStyle(wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER)); -} - -static void wxOsmo4_do_log(void *cbk, u32 level, u32 tool, const char *fmt, va_list list) -{ - wxOsmo4Frame *osmo = (wxOsmo4Frame *)cbk; - - if (osmo->m_logs) { - vfprintf(osmo->m_logs, fmt, list); - fflush(osmo->m_logs); - } else { - ::wxVLogMessage(wxString(fmt, wxConvUTF8), list); - } -} - - -Bool wxOsmo4Frame::LoadTerminal() -{ - m_term = NULL; - memset(&m_user, 0, sizeof(GF_User)); - - /*locate exec dir for cfg file*/ - wxPathList pathList; - wxString currentDir(wxGetCwd()); - wxString abs_gpac_path = wxT(""); - char *gpac_cfg, *sep; - - ::wxLogMessage(wxT("Looking for GPAC configuration file")); - - /*load config*/ - Bool first_launch = 0; - m_user.config = gf_cfg_init(NULL, &first_launch); - - if (!m_user.config) { - wxMessageDialog(NULL, wxT("Cannot open GPAC configuration file"), wxT("Init error"), wxOK); - return 0; - } - - gpac_cfg = gf_cfg_get_filename(m_user.config); - sep = strrchr(gpac_cfg, '/'); - if (!sep) sep = strrchr(gpac_cfg, '\\'); - if (sep) sep[0] = 0; - strcpy(szAppPath, gpac_cfg); - if (sep) sep[0] = '/'; - gf_free(gpac_cfg); - - /*check log file*/ - const char *str = gf_cfg_get_key(m_user.config, "General", "LogFile"); - if (str) m_logs = fopen(str, "wt"); - gf_log_set_callback(this, wxOsmo4_do_log); - - /*set log level*/ - gf_log_set_tools_levels( gf_cfg_get_key(m_user.config, "General", "Logs") ); - - gf_sys_init(0); - - ::wxLogMessage(wxT("GPAC configuration file opened - looking for modules")); - - m_user.modules = gf_modules_new(str, m_user.config); - /*initial launch*/ - if (!m_user.modules || !gf_modules_get_count(m_user.modules)) { - wxMessageDialog(NULL, wxT("No modules available - system cannot work"), wxT("Fatal Error"), wxOK).ShowModal(); - if (m_user.modules) gf_modules_del(m_user.modules); - gf_cfg_del(m_user.config); - m_user.config = NULL; - return 0; - } - - if (first_launch) { - u32 i; - for (i=0; iCanHandleURL(ifce, "test.test"); - gf_modules_close_interface((GF_BaseInterface *) ifce); - } - } - } - - - - ::wxLogMessage(wxT("%d modules found:"), gf_modules_get_count(m_user.modules)); - for (u32 i=0; im_pMain = this; - SetDropTarget(droptarget); - m_pLogs = new GPACLogs(this); - m_bGrabbed = 0; - - /*new menu bar*/ - wxMenuBar *b = new wxMenuBar(); - /*file*/ - wxMenu *menu = new wxMenu(); - menu->Append(GWX_FILE_OPEN, wxT("&Open File\tCtrl+O"), wxT("Open local presentation")); - menu->Append(GWX_FILE_OPEN_URL, wxT("&Open URL\tCtrl+U"), wxT("Open remote presentation")); - menu->AppendSeparator(); - menu->Append(FILE_PROPERTIES, wxT("&Properties\tCtrl+I"), wxT("Show presentation properties")); - menu->Enable(FILE_PROPERTIES, 0); - wxMenu *smenu = new wxMenu(); - smenu->Append(ID_MCACHE_ENABLE, wxT("&Enable"), wxT("Turns Recorder On/Off")); - smenu->Append(ID_MCACHE_STOP, wxT("&Stop"), wxT("Stops recording and saves")); - smenu->Append(ID_MCACHE_ABORT, wxT("&Abort"), wxT("Stops recording and discards")); - menu->Append(0, wxT("&Streaming Cache"), smenu); - menu->AppendSeparator(); - menu->Append(FILE_COPY, wxT("&Copy\tCtrl+C"), wxT("Copy selected text")); - menu->Append(FILE_PASTE, wxT("&Paste\tCtrl+V"), wxT("Copy selected text")); - menu->AppendSeparator(); - menu->Append(FILE_QUIT, wxT("E&xit"), wxT("Quit the application")); - b->Append(menu, wxT("&File")); - /*view*/ - menu = new wxMenu(); - vp_list = new wxMenu(); - menu->Append(0, wxT("&Viewpoint"), vp_list); - smenu = new wxMenu(); - smenu->Append(ID_HEADLIGHT, wxT("Headlight"), wxT("Turns headlight on/off"), wxITEM_CHECK); - smenu->AppendSeparator(); - smenu->Append(ID_NAVIGATE_NONE, wxT("None"), wxT("Disables Navigation"), wxITEM_CHECK); - smenu->Append(ID_NAVIGATE_WALK, wxT("Walk"), wxT("Walk Navigation"), wxITEM_CHECK); - smenu->Append(ID_NAVIGATE_FLY, wxT("Fly"), wxT("Fly Navigation"), wxITEM_CHECK); - smenu->Append(ID_NAVIGATE_EXAMINE, wxT("Examine"), wxT("Examine Navigation"), wxITEM_CHECK); - smenu->Append(ID_NAVIGATE_PAN, wxT("Pan"), wxT("Pan Navigation"), wxITEM_CHECK); - smenu->Append(ID_NAVIGATE_SLIDE, wxT("Slide"), wxT("Slide Navigation"), wxITEM_CHECK); - smenu->Append(ID_NAVIGATE_ORBIT, wxT("Orbit"), wxT("Orbit Navigation"), wxITEM_CHECK); - smenu->Append(ID_NAVIGATE_GAME, wxT("Game"), wxT("Game Navigation"), wxITEM_CHECK); - smenu->AppendSeparator(); - wxMenu *ssmenu = new wxMenu(); - ssmenu->Append(ID_COLLIDE_NONE, wxT("None"), wxT("No Collision detection"), wxITEM_CHECK); - ssmenu->Append(ID_COLLIDE_REG, wxT("Regular"), wxT("Regular Collision detection"), wxITEM_CHECK); - ssmenu->Append(ID_COLLIDE_DISP, wxT("Displacement"), wxT("Collision detecion with camera displacement"), wxITEM_CHECK); - smenu->Append(0, wxT("&Collision"), ssmenu); - smenu->Append(ID_GRAVITY, wxT("Gravity"), wxT("Turns gravity on/off"), wxITEM_CHECK); - smenu->AppendSeparator(); - smenu->Append(ID_NAVIGATE_RESET, wxT("Reset"), wxT("Reset Navigation")); - - menu->Append(0, wxT("&Navigation"), smenu); - menu->AppendSeparator(); - menu->Append(VIEW_FULLSCREEN, wxT("&Fullscreen"), wxT("Toggles Fullscreen"), wxITEM_CHECK); - menu->Append(VIEW_ORIGINAL, wxT("&Original Size"), wxT("Restore original size")); - smenu = new wxMenu(); - smenu->Append(VIEW_AR_KEEP, wxT("Keep Original\tCtrl+1"), wxT("Keep original aspect ratio"), wxITEM_CHECK); - smenu->Append(VIEW_AR_FILL, wxT("Fill Screen\tCtrl+2"), wxT("Stretch presentation to fill screen"), wxITEM_CHECK); - smenu->Append(VIEW_AR_43, wxT("Ratio 4/3\tCtrl+3"), wxT("Force aspect ratio to 4/3"), wxITEM_CHECK); - smenu->Append(VIEW_AR_169, wxT("Ratio 16/9\tCtrl+4"), wxT("Force aspect ratio to 16/9"), wxITEM_CHECK); - menu->Append(0, wxT("&Aspect Ratio"), smenu); - smenu->Check(VIEW_AR_KEEP, 1); - menu->AppendSeparator(); - menu->Append(VIEW_OPTIONS, wxT("&Options"), wxT("View Options")); - menu->AppendSeparator(); - menu->Append(VIEW_RTI, wxT("&Resource Usage"), wxT("View Resource Usage"), wxITEM_CHECK); - menu->Append(VIEW_LOGS, wxT("&Logs"), wxT("View GPAC logs")); - b->Append(menu, wxT("&View")); - - /*play*/ - menu = new wxMenu(); - sel_menu = new wxMenu(); - sel_menu->Append(0, wxT("&Audio"), new wxMenu()); - sel_menu->Append(0, wxT("&Video"), new wxMenu()); - sel_menu->Append(0, wxT("&Subtitles"), new wxMenu()); - sel_menu->AppendSeparator(); - sel_menu->Append(ID_ADD_SUB, wxT("&Add Subtitle"), wxT("Adds subtitle")); - menu->Append(ID_STREAM_MENU, wxT("&Streams Selection"), sel_menu); - chap_menu = new wxMenu(); - menu->Append(ID_CHAPTER_MENU, wxT("&Chapters"), chap_menu); - - menu->AppendSeparator(); - menu->Append(VIEW_PLAYLIST, wxT("&Playlist\tCtrl+L"), wxT("Show navigation history as playlist"), wxITEM_CHECK); - menu->Append(ID_CLEAR_NAV, wxT("&Clear History"), wxT("Clear navigation history")); - menu->AppendSeparator(); - menu->Append(FILE_PLAY, wxT("&Play/Pause\tCtrl+P"), wxT("Play/Pause/Resume Presentation")); - menu->Append(FILE_STEP, wxT("&Step-by-Step\tCtrl+S"), wxT("Play/Pause/Resume Presentation")); - menu->Append(FILE_STOP, wxT("&Stop"), wxT("Stop Presentation")); - menu->AppendSeparator(); - menu->Append(FILE_RELOAD_CONFIG, wxT("&Reload Config\tCtrl+R"), wxT("Reload Configuration File")); - menu->Append(FILE_RELOAD, wxT("&Reload File\tCtrl+R"), wxT("Reload Presentation")); - b->Append(menu, wxT("&Play")); - - menu = new wxMenu(); - menu->Append(APP_SHORTCUTS, wxT("&Shortcuts"), wxT("Show keyboard shortcuts")); - menu->Append(APP_NAV_KEYS, wxT("&Navigation Keys"), wxT("Show navigation keys")); - menu->AppendSeparator(); - menu->Append(APP_ABOUT, wxT("&About"), wxT("Display information and copyright")); - b->Append(menu, wxT("&?")); - - SetMenuBar(b); - - m_pStatusbar = CreateStatusBar(1, 0, -1, wxT("statusBar")); - ws[0] = 60; - ws[1] = 70; - ws[2] = -1; - m_pStatusbar->SetFieldsCount(3, ws); - - SetStatusBarPane(2); - wxColour foreCol = m_pStatusbar->GetBackgroundColour(); - SetBackgroundColour(foreCol); - - - m_pTimer = new wxTimer(); - m_pTimer->SetOwner(this, ID_CTRL_TIMER); - m_bGrabbed = 0; - - /*create toolbar*/ - m_pToolBar = CreateToolBar(wxTB_FLAT|wxTB_HORIZONTAL); - m_pOpenFile = new wxBitmap(tool_open_file); - m_pPrev = new wxBitmap(tool_prev); - m_pNext = new wxBitmap(tool_next); - m_pPlay = new wxBitmap(tool_play); - m_pPause = new wxBitmap(tool_pause); - m_pStep = new wxBitmap(tool_step); - m_pStop = new wxBitmap(tool_stop); - m_pInfo = new wxBitmap(tool_info); - m_pConfig = new wxBitmap(tool_config); - m_pSW2D = new wxBitmap(tool_sw_2d); - m_pSW3D = new wxBitmap(tool_sw_3d); - - m_pToolBar->AddTool(GWX_FILE_OPEN, wxT(""), *m_pOpenFile, wxT("Open File")); - m_pToolBar->AddSeparator(); - m_pPrevBut = new wxMenuButton(m_pToolBar, FILE_PREV, *m_pPrev); - m_pPrevBut->SetToolTip(wxT("Previous Location")); - m_pToolBar->AddControl(m_pPrevBut); - m_pNextBut = new wxMenuButton(m_pToolBar, FILE_NEXT, *m_pNext); - m_pNextBut->SetToolTip(wxT("Next Location")); - m_pToolBar->AddControl(m_pNextBut); - - m_pToolBar->AddSeparator(); - m_pToolBar->AddTool(FILE_PLAY, wxT(""), *m_pPlay, wxT("Play/Pause File")); - m_pToolBar->AddTool(FILE_STEP, wxT(""), *m_pStep, wxT("Step-by-Step Mode")); - m_pToolBar->AddTool(FILE_STOP, wxT(""), *m_pStop, wxT("Stop File")); - m_pToolBar->AddSeparator(); - m_pToolBar->AddTool(FILE_PROPERTIES, wxT(""), *m_pInfo, wxT("Show File Information")); - m_pToolBar->AddSeparator(); - m_pToolBar->AddTool(VIEW_OPTIONS, wxT(""), *m_pConfig, wxT("GPAC Configuration")); - m_pToolBar->AddTool(SWITCH_RENDER, wxT(""), *m_pSW3D, wxT("Switch 2D/3D Renderers")); - - m_pToolBar->Realize(); - - m_Address = new wxMyComboBox(this, ID_ADDRESS, wxT(""), wxPoint(50, 0), wxSize(80, 20)); - wxStaticText *add_text = new wxStaticText(this, -1, wxT("URL"), wxPoint(0, 0), wxSize(40, 20)); - add_text->SetBackgroundColour(foreCol); - - m_pAddBar = new wxBoxSizer(wxHORIZONTAL); - m_pAddBar->Add(add_text, 0, wxALIGN_TOP); - m_pAddBar->Add(m_Address, 2, wxALIGN_CENTER|wxEXPAND|wxADJUST_MINSIZE); - m_pAddBar->SetMinSize(80, 32); - m_pAddBar->Layout(); - - m_pProg = new wxSlider(this, ID_SLIDER, 0, 0, 1000, wxPoint(0, 22), wxSize(80, 22), wxSL_HORIZONTAL|wxSUNKEN_BORDER); - m_pProg->Enable(0); - m_pProg->Show(); - m_pProg->SetBackgroundColour(foreCol); - - m_pView = new wxWindow(this, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); - m_pView->SetBackgroundColour(wxColour(wxT("BLACK"))); -#ifdef __WXGTK__ - m_pVisual = new wxWindow(m_pView, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); - m_pVisual->SetBackgroundColour(wxColour(wxT("BLACK"))); -#endif - - m_pPlayList = new wxPlaylist(this); - m_pPlayList->SetIcon(wxIcon(osmo4)); - m_pPlayList->Hide(); - Raise(); - Show(); - - m_connected = 0; - if (!LoadTerminal()) { - Close(TRUE); - return; - } - - - - if (m_bExternalView) SetWindowStyle(wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER)); - DoLayout(320, 240); - UpdateRenderSwitch(); - - const char *sOpt = gf_cfg_get_key(m_user.config, "General", "ConsoleOff"); - m_console_off = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; - sOpt = gf_cfg_get_key(m_user.config, "General", "Loop"); - m_loop = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; - sOpt = gf_cfg_get_key(m_user.config, "General", "LookForSubtitles"); - m_lookforsubs = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; - gf_term_set_option(m_term, GF_OPT_AUDIO_VOLUME, 100); - - ReloadURLs(); - Raise(); - m_pStatusbar->SetStatusText(wxT("Ready"), 2); - m_LastStatusTime = 0; - - m_pPrevBut->Refresh(); - m_pNextBut->Refresh(); - - wxOsmo4App &app = wxGetApp(); - if (app.argc>1) { - m_pPlayList->QueueURL(wxString(app.argv[1])); - m_pPlayList->RefreshList(); - m_pPlayList->PlayNext(); - } else { - char sPL[GF_MAX_PATH]; - strcpy((char *) sPL, szAppPath); -#ifdef WIN32 - strcat(sPL, "gpac_pl.m3u"); -#else - strcat(sPL, ".gpac_pl.m3u"); -#endif - m_pPlayList->OpenPlaylist(wxString(sPL, wxConvUTF8) ); - const char *sOpt = gf_cfg_get_key(m_user.config, "General", "PLEntry"); - if (sOpt) { - m_pPlayList->m_cur_entry = atoi(sOpt); - if (m_pPlayList->m_cur_entry>=(s32)gf_list_count(m_pPlayList->m_entries)) - m_pPlayList->m_cur_entry = -1; - } - - sOpt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); - if (sOpt) { - gf_term_connect(m_term, sOpt); - m_bStartupFile = 1; - } - } - - sOpt = gf_cfg_get_key(m_user.config, "Audio", "DriverName"); - - if (!strcmp(sOpt, "No Audio Output Available")) { - ::wxLogMessage(wxT("WARNING: no audio output availble - make sure no other program is locking the sound card")); - SetStatus(wxT("No audio ouput available")); - - } else { - SetStatus(wxT("Ready")); - } -} - -wxOsmo4Frame::~wxOsmo4Frame() -{ - vp_list = NULL; - sel_menu = NULL; - - if (m_user.modules) gf_modules_del(m_user.modules); - gf_sys_close(); - if (m_user.config) gf_cfg_del(m_user.config); - - if (m_chapters_start) gf_free(m_chapters_start); - if (m_pView) delete m_pView; - - //m_pToolBar->RemoveTool(FILE_PREV); - //m_pToolBar->RemoveTool(FILE_NEXT); - - delete m_pPrevBut; - delete m_pNextBut; - delete m_pPlayList; - delete m_pTimer; - delete m_pOpenFile; - delete m_pPrev; - delete m_pNext; - delete m_pPlay; - delete m_pPause; - delete m_pStep; - delete m_pStop; - delete m_pInfo; - delete m_pConfig; - delete m_pSW2D; - delete m_pSW3D; -} - - -BEGIN_EVENT_TABLE(wxOsmo4Frame, wxFrame) - EVT_CLOSE(wxOsmo4Frame::OnCloseApp) - EVT_MENU(GWX_FILE_OPEN, wxOsmo4Frame::OnFileOpen) - EVT_MENU(GWX_FILE_OPEN_URL, wxOsmo4Frame::OnFileOpenURL) - EVT_MENU(FILE_RELOAD_CONFIG, wxOsmo4Frame::OnFileReloadConfig) - EVT_MENU(FILE_RELOAD, wxOsmo4Frame::OnFileReload) - EVT_MENU(FILE_PROPERTIES, wxOsmo4Frame::OnFileProperties) - EVT_MENU(FILE_QUIT, wxOsmo4Frame::OnFileQuit) - EVT_MENU(VIEW_FULLSCREEN, wxOsmo4Frame::OnFullScreen) - EVT_MENU(VIEW_OPTIONS, wxOsmo4Frame::OnOptions) - EVT_MENU(VIEW_AR_KEEP, wxOsmo4Frame::OnViewARKeep) - EVT_MENU(VIEW_AR_FILL, wxOsmo4Frame::OnViewARFill) - EVT_MENU(VIEW_AR_169, wxOsmo4Frame::OnViewAR169) - EVT_MENU(VIEW_AR_43, wxOsmo4Frame::OnViewAR43) - EVT_MENU(VIEW_ORIGINAL, wxOsmo4Frame::OnViewOriginal) - EVT_MENU(VIEW_PLAYLIST, wxOsmo4Frame::OnPlaylist) - EVT_UPDATE_UI(VIEW_PLAYLIST, wxOsmo4Frame::OnUpdatePlayList) - EVT_MENU(FILE_COPY, wxOsmo4Frame::OnFileCopy) - EVT_UPDATE_UI(FILE_COPY, wxOsmo4Frame::OnUpdateFileCopy) - EVT_MENU(FILE_PASTE, wxOsmo4Frame::OnFilePaste) - EVT_UPDATE_UI(FILE_PASTE, wxOsmo4Frame::OnUpdateFilePaste) - - EVT_MENU(ID_CLEAR_NAV, wxOsmo4Frame::OnClearNav) - EVT_UPDATE_UI(ID_STREAM_MENU, wxOsmo4Frame::OnUpdateStreamMenu) - EVT_UPDATE_UI(ID_CHAPTER_MENU, wxOsmo4Frame::OnUpdateChapterMenu) - EVT_MENU(ID_ADD_SUB, wxOsmo4Frame::OnAddSub) - - EVT_MENU(ID_MCACHE_ENABLE, wxOsmo4Frame::OnCacheEnable) - EVT_UPDATE_UI(ID_MCACHE_ENABLE, wxOsmo4Frame::OnUpdateCacheEnable) - EVT_MENU(ID_MCACHE_STOP, wxOsmo4Frame::OnCacheStop) - EVT_MENU(ID_MCACHE_ABORT, wxOsmo4Frame::OnCacheAbort) - EVT_UPDATE_UI(ID_MCACHE_STOP, wxOsmo4Frame::OnUpdateCacheAbort) - EVT_UPDATE_UI(ID_MCACHE_ABORT, wxOsmo4Frame::OnUpdateCacheAbort) - - - EVT_MENU(APP_SHORTCUTS, wxOsmo4Frame::OnShortcuts) - EVT_MENU(APP_NAV_KEYS, wxOsmo4Frame::OnNavInfo) - EVT_MENU(APP_ABOUT, wxOsmo4Frame::OnAbout) - EVT_GPACEVENT(wxOsmo4Frame::OnGPACEvent) - EVT_TIMER(ID_CTRL_TIMER, wxOsmo4Frame::OnTimer) - EVT_COMMAND_SCROLL(ID_SLIDER, wxOsmo4Frame::OnSlide) - EVT_MENU(VIEW_LOGS, wxOsmo4Frame::OnLogs) - EVT_MENU(VIEW_RTI, wxOsmo4Frame::OnRTI) - - EVT_MENUBUTTON_OPEN(FILE_PREV, wxOsmo4Frame::OnFilePrevOpen) - EVT_MENUBUTTON_OPEN(FILE_NEXT, wxOsmo4Frame::OnFileNextOpen) - EVT_MENU(FILE_PREV, wxOsmo4Frame::OnNavPrev) - EVT_UPDATE_UI(FILE_PREV, wxOsmo4Frame::OnUpdateNavPrev) - EVT_MENU_RANGE(ID_NAV_PREV_0, ID_NAV_PREV_9, wxOsmo4Frame::OnNavPrevMenu) - EVT_MENU(FILE_NEXT, wxOsmo4Frame::OnNavNext) - EVT_UPDATE_UI(FILE_NEXT, wxOsmo4Frame::OnUpdateNavNext) - EVT_MENU_RANGE(ID_NAV_NEXT_0, ID_NAV_NEXT_9, wxOsmo4Frame::OnNavNextMenu) - - EVT_TOOL(FILE_PLAY, wxOsmo4Frame::OnFilePlay) - EVT_TOOL(FILE_STEP, wxOsmo4Frame::OnFileStep) - EVT_TOOL(FILE_STOP, wxOsmo4Frame::OnFileStop) - EVT_TOOL(SWITCH_RENDER, wxOsmo4Frame::OnRenderSwitch) - - EVT_COMBOBOX(ID_ADDRESS, wxOsmo4Frame::OnURLSelect) - - EVT_MENU_RANGE(ID_SELSTREAM_0, ID_SELSTREAM_9, wxOsmo4Frame::OnStreamSel) - EVT_UPDATE_UI_RANGE(ID_SELSTREAM_0, ID_SELSTREAM_9, wxOsmo4Frame::OnUpdateStreamSel) - - EVT_MENU_RANGE(ID_SETCHAP_FIRST, ID_SETCHAP_LAST, wxOsmo4Frame::OnChapterSel) - EVT_UPDATE_UI_RANGE(ID_SETCHAP_FIRST, ID_SETCHAP_LAST, wxOsmo4Frame::OnUpdateChapterSel) - - EVT_MENU_RANGE(ID_VIEWPOINT_FIRST, ID_VIEWPOINT_LAST, wxOsmo4Frame::OnViewport) - EVT_UPDATE_UI_RANGE(ID_VIEWPOINT_FIRST, ID_VIEWPOINT_LAST, wxOsmo4Frame::OnUpdateViewport) - - EVT_MENU_RANGE(ID_NAVIGATE_NONE, ID_NAVIGATE_GAME, wxOsmo4Frame::OnNavigate) - EVT_UPDATE_UI_RANGE(ID_NAVIGATE_NONE, ID_NAVIGATE_GAME, wxOsmo4Frame::OnUpdateNavigation) - EVT_MENU(ID_NAVIGATE_RESET, wxOsmo4Frame::OnNavigateReset) - - EVT_MENU_RANGE(ID_COLLIDE_NONE, ID_COLLIDE_DISP, wxOsmo4Frame::OnCollide) - EVT_UPDATE_UI_RANGE(ID_COLLIDE_NONE, ID_COLLIDE_DISP, wxOsmo4Frame::OnUpdateCollide) - - EVT_MENU(ID_HEADLIGHT, wxOsmo4Frame::OnHeadlight) - EVT_UPDATE_UI(ID_HEADLIGHT, wxOsmo4Frame::OnUpdateHeadlight) - EVT_MENU(ID_GRAVITY, wxOsmo4Frame::OnGravity) - EVT_UPDATE_UI(ID_GRAVITY, wxOsmo4Frame::OnUpdateGravity) - - EVT_UPDATE_UI(FILE_PROPERTIES, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(FILE_RELOAD, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(FILE_PLAY, wxOsmo4Frame::OnUpdatePlay) - EVT_UPDATE_UI(FILE_STOP, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(FILE_STEP, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(VIEW_ORIGINAL, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(VIEW_FULLSCREEN, wxOsmo4Frame::OnUpdateFullScreen) - EVT_UPDATE_UI(VIEW_AR_KEEP, wxOsmo4Frame::OnUpdateAR) - EVT_UPDATE_UI(VIEW_AR_FILL, wxOsmo4Frame::OnUpdateAR) - EVT_UPDATE_UI(VIEW_AR_169, wxOsmo4Frame::OnUpdateAR) - EVT_UPDATE_UI(VIEW_AR_43, wxOsmo4Frame::OnUpdateAR) - - EVT_SIZE(wxOsmo4Frame::OnSize) -END_EVENT_TABLE() - -void wxOsmo4Frame::DoLayout(u32 v_width, u32 v_height) -{ - wxPoint pos; - if (!m_Address || !m_pProg) return; - - int t_h = m_pToolBar->GetSize().y; - int a_h = m_pAddBar->GetSize().y; - int p_h = m_pProg->GetSize().y; - - if (m_bExternalView) { - if (v_width && v_height) { - m_orig_width = v_width; - m_orig_height = v_height; - } - SetClientSize(320, a_h+p_h+t_h); - m_pAddBar->SetDimension(0,0, 320, a_h); - m_pProg->SetSize(0, t_h+a_h, 320, p_h, 0); - return; - } - - if (v_width && v_height) { - m_orig_width = v_width; - m_orig_height = v_height; - v_height += a_h + p_h + t_h; - SetClientSize(v_width, v_height); - m_pView->SetSize(0, a_h+t_h, v_width, v_height, 0); - m_pAddBar->SetDimension(0, t_h, v_width, a_h); - m_pProg->SetSize(0, v_height - p_h, v_width, p_h, 0); - } - wxSize s = GetClientSize(); - s.y -= a_h + p_h + t_h; - if (m_pView) { - m_pView->SetSize(0, a_h+t_h, s.x, s.y, 0); - m_pAddBar->SetDimension(0, 0, s.x, a_h); - m_pAddBar->SetDimension(0, 0, s.x, a_h); - m_pAddBar->Layout(); - m_pProg->SetSize(0, s.y+t_h+a_h, s.x, p_h, 0); - if (m_term) gf_term_set_size(m_term, s.x, s.y); - } -} - -void wxOsmo4Frame::OnSize(wxSizeEvent &event) -{ - DoLayout(); -} - -void wxOsmo4Frame::OnCloseApp(wxCloseEvent &WXUNUSED(event)) -{ - if (m_term) gf_term_del(m_term); - m_term = NULL; - Destroy(); -} - - -wxString wxOsmo4Frame::GetFileFilter() -{ - u32 keyCount, i; - wxString sFiles, sSupportedFiles, sExts; - - /*force MP4 and 3GP files at beginning to make sure they are selected (Win32 bug with too large filters)*/ - sSupportedFiles = wxT("All Known Files|*.m3u;*.pls;*.mp4;*.3gp;*.3g2"); - sExts = wxT(""); - sFiles = wxT(""); - keyCount = gf_cfg_get_key_count(m_user.config, "MimeTypes"); - for (i=0; i=0) continue; - /*if same extensions for # mime types skip (don't polluate the file list)*/ - if (sExts.Find(wxString(szKeyList, wxConvUTF8) )>=0) continue; - - sExts += wxString(szKeyList, wxConvUTF8); - sExts += wxT(" "); - sFiles += wxString(sDesc, wxConvUTF8); - sFiles += wxT("|"); - - wxString sOpt = wxString(szKeyList, wxConvUTF8); - while (1) { - wxString ext = sOpt.BeforeFirst(' '); - if (ext.Find('.')<0) { - if (first) first = 0; - else sFiles += wxT(";"); - sFiles += wxT("*."); - sFiles += ext; - wxString sext = ext; - sext += wxT(";"); - if (sSupportedFiles.Find(sext)<0) { - sSupportedFiles += wxT(";*."); - sSupportedFiles += ext; - } - } - if (sOpt==ext) break; - wxString rem = ext + wxT(" "); - sOpt.Replace(rem, wxT(""), TRUE); - } - sFiles += wxT("|"); - } - sSupportedFiles += wxT("|"); - sSupportedFiles += sFiles; - sSupportedFiles += wxT("M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|All Files|*.*||"); - return sSupportedFiles; -} - -void wxOsmo4Frame::OnFileOpen(wxCommandEvent & WXUNUSED(event)) -{ - wxFileDialog dlg(this, wxT("Select file(s)"), wxT(""), wxT(""), GetFileFilter(), wxOPEN | wxMULTIPLE | wxCHANGE_DIR /*| wxHIDE_READONLY*/); - - if (dlg.ShowModal() != wxID_OK) return; - - wxArrayString stra; - dlg.GetPaths(stra); - if (stra.GetCount() == 1) { - m_pPlayList->Truncate(); - } else { - m_pPlayList->Clear(); - } - for (u32 i=0; iQueueURL(stra[i]); - - m_pPlayList->RefreshList(); - m_pPlayList->PlayNext(); -} - -void wxOsmo4Frame::OnFileOpenURL(wxCommandEvent & WXUNUSED(event)) -{ - OpenURLDlg dlg(this, m_user.config); - if (dlg.ShowModal()==wxID_OK) { - m_pPlayList->Truncate(); - m_pPlayList->QueueURL(dlg.m_urlVal); - m_pPlayList->RefreshList(); - m_pPlayList->PlayNext(); - } -} - -void wxOsmo4Frame::OnFileProperties(wxCommandEvent & WXUNUSED(event)) -{ - wxFileProps dlg(this); - dlg.SetIcon(wxIcon(osmo4)); - dlg.ShowModal(); -} - -void wxOsmo4Frame::OnFileReload(wxCommandEvent & WXUNUSED(event)) -{ - gf_term_disconnect(m_term); - m_connected = 0; - DoConnect(); -} - -void wxOsmo4Frame::OnFileReloadConfig(wxCommandEvent & WXUNUSED(event)) -{ - gf_term_set_option(m_term, GF_OPT_RELOAD_CONFIG, 1); -} - -void wxOsmo4Frame::OnFileQuit(wxCommandEvent & WXUNUSED(event)) -{ - Close(FALSE); -} - -void wxOsmo4Frame::OnViewOriginal(wxCommandEvent & WXUNUSED(event)) -{ - if (!m_bExternalView) { - DoLayout(m_orig_width, m_orig_height); - } else { - gf_term_set_option(m_term, GF_OPT_ORIGINAL_VIEW, 1); - } -} - -void wxOsmo4Frame::OnOptions(wxCommandEvent & WXUNUSED(event)) -{ - wxGPACControl dlg(this); - dlg.SetIcon(wxIcon(osmo4)); - dlg.ShowModal(); -} - -void wxOsmo4Frame::DoConnect() -{ - //if (m_connected) { gf_term_disconnect(m_term); m_connected = 0; } - - wxString url = m_pPlayList->GetURL(); - m_Address->SetValue(url); -#ifdef __WXGTK__ - m_pVisual->SetFocus(); -#else - m_pView->SetFocus(); -#endif - wxString txt = wxT("Osmo4 - "); - txt += m_pPlayList->GetDisplayName(); - SetTitle(txt); - m_bStartupFile = 0; - gf_term_connect(m_term, url.mb_str(wxConvUTF8)); -} - -void wxOsmo4Frame::OnLogs(wxCommandEvent & WXUNUSED(event)) -{ - m_pLogs->Show(); -} - -void wxOsmo4Frame::OnUpdateNeedsConnect(wxUpdateUIEvent &event) -{ - event.Enable(m_connected ? 1 : 0); -} - -void wxOsmo4Frame::OnUpdatePlay(wxUpdateUIEvent &event) -{ - event.Enable( (m_connected || m_pPlayList->HasValidEntries()) ? 1 : 0); -} - -void wxOsmo4Frame::OnUpdateFullScreen(wxUpdateUIEvent &event) -{ - if (m_connected) { - event.Enable(1); - event.Check(gf_term_get_option(m_term, GF_OPT_FULLSCREEN) ? 1 : 0); - } else { - event.Enable(0); - } -} - -void wxOsmo4Frame::OnFullScreen(wxCommandEvent & WXUNUSED(event)) -{ - Bool isFS = gf_term_get_option(m_term, GF_OPT_FULLSCREEN) ? 1 : 0; - gf_term_set_option(m_term, GF_OPT_FULLSCREEN, isFS ? 0 : 1); -} - -void wxOsmo4Frame::OnViewARKeep(wxCommandEvent & WXUNUSED(event)) -{ - gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); -} -void wxOsmo4Frame::OnViewARFill(wxCommandEvent & WXUNUSED(event)) -{ - gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); -} -void wxOsmo4Frame::OnViewAR169(wxCommandEvent & WXUNUSED(event)) -{ - gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); -} -void wxOsmo4Frame::OnViewAR43(wxCommandEvent & WXUNUSED(event)) -{ - gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); -} - -void wxOsmo4Frame::OnUpdateAR(wxUpdateUIEvent &event) -{ - if (!m_connected) { - event.Enable(0); - return; - } - event.Enable(1); - u32 val = gf_term_get_option(m_term, GF_OPT_ASPECT_RATIO); - if ((event.GetId() == VIEW_AR_FILL) && (val==GF_ASPECT_RATIO_FILL_SCREEN)) - event.Check(1); - else if ((event.GetId() == VIEW_AR_KEEP) && (val==GF_ASPECT_RATIO_KEEP)) - event.Check(1); - else if ((event.GetId() == VIEW_AR_169) && (val==GF_ASPECT_RATIO_16_9)) - event.Check(1); - else if ((event.GetId() == VIEW_AR_43) && (val==GF_ASPECT_RATIO_4_3)) - event.Check(1); - else event.Check(0); -} - -void wxOsmo4Frame::OnShortcuts(wxCommandEvent & WXUNUSED(event)) -{ - wxMessageDialog dlg(this, - wxT("Shortcuts with focus on main frame:\n") - wxT("Open File: Ctrl + O\n") - wxT("Show File Information: Ctrl + I\n") - wxT("Reload File: Ctrl + R\n") - wxT("Pause/Resume File: Ctrl + P\n") - wxT("Step by Step: Ctrl + S\n") - wxT("Fullscreen On/Off: Alt + Return\n") - wxT("View Playlist: Ctrl + L\n") - wxT("Aspect Ratio Normal: Ctrl + 1\n") - wxT("Aspect Ratio Fill: Ctrl + 2\n") - wxT("Aspect Ratio 4/3: Ctrl + 3\n") - wxT("Aspect Ratio 16/9: Ctrl + 4\n") - wxT("\n") - wxT("Shortcuts with focus on video frame:\n") - wxT("Seek +5% into presentation: Alt + right arrow\n") - wxT("Seek -5% into presentation: Alt + left arrow\n") - wxT("Seek +1min into presentation: Alt + up arrow\n") - wxT("Seek -1min into presentation: Alt + down arrow\n") - wxT("Next Playlist Entry: Ctrl + right arrow\n") - wxT("Prev Playlist Entry: Ctrl + left arrow\n") - - , wxT("Shortcuts Available on Osmo4") - , wxOK); - - dlg.ShowModal(); -} - -void wxOsmo4Frame::OnNavInfo(wxCommandEvent & WXUNUSED(event)) -{ - wxMessageDialog dlg(this, - wxT("* Walk & Fly modes:\n") - wxT("\tH move: H pan - V move: Z-translate - V move+CTRL or Wheel: V pan - Right Click (Walk only): Jump\n") - wxT("\tleft/right: H pan - left/right+CTRL: H translate - up/down: Z-translate - up/down+CTRL: V pan\n") - wxT("* Pan mode:\n") - wxT("\tH move: H pan - V move: V pan - V move+CTRL or Wheel: Z-translate\n") - wxT("\tleft/right: H pan - left/right+CTRL: H translate - up/down: V pan - up/down+CTRL: Z-translate\n") - wxT("* Slide mode:\n") - wxT("\tH move: H translate - V move: V translate - V move+CTRL or Wheel: Z-translate\n") - wxT("\tleft/right: H translate - left/right+CTRL: H pan - up/down: V translate - up/down+CTRL: Z-translate\n") - wxT("* Examine & Orbit mode:\n") - wxT("\tH move: Y-Axis rotate - H move+CTRL: No move - V move: X-Axis rotate - V move+CTRL or Wheel: Z-translate\n") - wxT("\tleft/right: Y-Axis rotate - left/right+CTRL: H translate - up/down: X-Axis rotate - up/down+CTRL: Y-translate\n") - wxT("* VR mode:\n") - wxT("\tH move: H pan - V move: V pan - V move+CTRL or Wheel: Camera Zoom\n") - wxT("\tleft/right: H pan - up/down: V pan - up/down+CTRL: Camera Zoom\n") - wxT("* Game mode (press END to escape):\n") - wxT("\tH move: H pan - V move: V pan\n") - wxT("\tleft/right: H translate - up/down: Z-translate\n") - wxT("\n") - wxT("* All 3D modes: CTRL+PGUP/PGDOWN will zoom in/out camera (field of view) \n") - wxT("\n") - wxT("*Slide Mode in 2D:\n") - wxT("\tH move: H translate - V move: V translate - V move+CTRL: zoom\n") - wxT("\tleft/right: H translate - up/down: V translate - up/down+CTRL: zoom\n") - wxT("*Examine Mode in 2D (3D renderer only):\n") - wxT("\tH move: Y-Axis rotate - V move: X-Axis rotate\n") - wxT("\tleft/right: Y-Axis rotate - up/down: X-Axis rotate\n") - wxT("\n") - wxT("HOME: reset navigation to last viewpoint (2D or 3D navigation)\n") - wxT("SHIFT key in all modes: fast movement\n") - - , wxT("3D navigation keys (\'H\'orizontal and \'V\'ertical) used in GPAC") - , wxOK ); - dlg.ShowModal(); -} - - -/*open file dlg*/ -class AboutDlg : public wxDialog { -public: - AboutDlg(wxWindow *parent); - -private: - wxStaticText *m_info; - wxButton *m_close; - void OnClose(wxCommandEvent& event); - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(AboutDlg, wxDialog) - EVT_BUTTON(ID_ABOUT_CLOSE, AboutDlg::OnClose) -END_EVENT_TABLE() - -AboutDlg::AboutDlg(wxWindow *parent) - : wxDialog(parent, -1, wxString(wxT("GPAC/Osmo4 V ")wxT(GPAC_FULL_VERSION))) -{ - SetSize(220, 320); - Centre(); - wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); - - m_info = new wxStaticText(this, -1, wxT("http://gpac.sourceforge.net"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); - sizer->Add(m_info, 1, wxEXPAND|wxADJUST_MINSIZE, 0); - m_close = new wxButton(this, ID_ABOUT_CLOSE, wxT("Close"), wxDefaultPosition, wxSize(120, 20)); - sizer->Add(m_close, 0, wxEXPAND, 0); - - SetIcon(wxIcon(osmo4)); - m_info->SetLabel( - wxT("Osmo4 Player\n") - wxT("GPAC Multimedia Framework\n") - wxT("\n") - wxT("This program is gf_free software and may\n") - wxT("be distributed according to the terms\n") - wxT("of the GNU Lesser General Public License\n") - wxT("\n") - wxT("Copyright (c) Jean Le Feuvre 2000-2005\n") - wxT("(c) ENST 2005-200X\n") - wxT("All Rights Reserved\n") - wxT("http://gpac.sourceforge.net\n") - wxT("\n") - wxT(" ** With Many Thanks To ** \n\n") - wxT("Mozilla SpiderMonkey (JavaScript)\n") - wxT("The FreeType Project\n") - wxT("The PNG Group, The I.J.G.\n") - wxT("FFMPEG, FAAD, XVID, MAD\n") - ); - - SetSizer(sizer); - sizer->Fit(this); -} -void AboutDlg::OnClose(wxCommandEvent& WXUNUSED(event)) -{ - Close(FALSE); -} - -void wxOsmo4Frame::OnAbout(wxCommandEvent & WXUNUSED(event)) -{ - AboutDlg dlg(this); - dlg.ShowModal(); -} - - -void wxOsmo4Frame::OnGPACEvent(wxGPACEvent &event) -{ - wxString cmd; - wxCommandEvent evt; - if (!m_term) return; - - switch (event.gpac_evt.type) { - case GF_EVENT_NAVIGATE: - if (gf_term_is_supported_url(m_term, event.to_url.mb_str(wxConvUTF8), 1, 0)) { - char *str = gf_url_concatenate(m_pPlayList->GetURL().mb_str(wxConvUTF8), event.to_url.mb_str(wxConvUTF8)); - if (str) { - m_pPlayList->Truncate(); - m_pPlayList->QueueURL(wxString(str, wxConvUTF8)); - m_pPlayList->RefreshList(); - gf_free(str); - m_pPlayList->PlayNext(); - } - return; - } - cmd = get_pref_browser(m_user.config); - if (cmd.IsEmpty()){ - cmd += wxT(" "); - cmd += event.to_url; - wxExecute(cmd); - } else { -#ifdef wxLaunchDefaultBrowser - wxLaunchDefaultBrowser(event.to_url); -#endif - } - break; - case GF_EVENT_QUIT: - Close(TRUE); - break; - case GF_EVENT_SET_CAPTION: - SetTitle(event.to_url); - break; - case GF_EVENT_CONNECT: - BuildStreamList(0); - ConnectAcknowledged(event.gpac_evt.connect.is_connected); - break; - case GF_EVENT_KEYDOWN: - if (!(event.gpac_evt.key.flags & GF_KEY_MOD_CTRL)) return; - switch (event.gpac_evt.key.key_code) { - case GF_KEY_R: - gf_term_set_option(m_term, GF_OPT_REFRESH, 1); - break; - case GF_KEY_P: - OnFilePlay(evt); - break; - case GF_KEY_S: - OnFileStep(evt); - break; - } - break; - case GF_EVENT_SCENE_SIZE: - m_orig_width = event.gpac_evt.size.width; - m_orig_height = event.gpac_evt.size.height; - case GF_EVENT_SIZE: - if (! gf_term_get_option(m_term, GF_OPT_FULLSCREEN)) { - DoLayout(event.gpac_evt.size.width, event.gpac_evt.size.height); - } - break; - case GF_EVENT_VIEWPOINTS: - BuildViewList(); - break; - case GF_EVENT_STREAMLIST: - BuildStreamList(0); - break; - } -} - - -static wxString format_time(u32 duration, u32 timescale) -{ - u32 h, m, s; - Float time = duration; - time /= timescale; - time *= 1000; - h = (u32) (time / 1000 / 3600); - m = (u32) (time / 1000 / 60 - h*60); - s = (u32) (time / 1000 - h*3600 - m*60); - return wxString::Format(wxT("%02d:%02d:%02d"), h, m, s); -} - -void wxOsmo4Frame::SetStatus(wxString str) -{ - //m_pStatusbar->SetStatusText(str, 2); - m_LastStatusTime = gf_sys_clock(); -} - -#define RTI_REFRESH_MS 500 -void wxOsmo4Frame::OnRTI(wxCommandEvent & event) -{ - m_bViewRTI = event.IsChecked(); - if (m_bViewRTI) { - if (!m_pTimer->IsRunning()) m_pTimer->Start(RTI_REFRESH_MS, 0); - } else if (!m_connected && m_pTimer->IsRunning()) { - m_LastStatusTime = 0; - m_pStatusbar->SetStatusText(wxT("Ready"), 2); - m_pTimer->Stop(); - } -} - -void wxOsmo4Frame::OnTimer(wxTimerEvent& WXUNUSED(event)) -{ - wxString str; - u32 now; - if (m_LastStatusTime) { - now = gf_sys_clock(); - if (now > 1000+m_LastStatusTime) { - m_LastStatusTime = 0; - m_pStatusbar->SetStatusText(wxT("Ready"), 2); - } - } - - if (m_bViewRTI) { - GF_SystemRTInfo rti; - if (!gf_sys_get_rti(RTI_REFRESH_MS, &rti, 0)) return; - if (rti.gpac_memory) rti.process_memory = rti.gpac_memory; - - str = wxString::Format(wxT("CPU %02d (%02d) - Mem %d kB" ), - rti.total_cpu_usage, rti.process_cpu_usage, rti.gpac_memory/1024); - - m_pStatusbar->SetStatusText(str, 2); - } - if (!m_connected) return; - - now = gf_term_get_time_in_ms(m_term); - if (!now) return; - - if (!m_duration) { - str = format_time(now, 1000); - m_pStatusbar->SetStatusText(str); - str = wxString::Format(wxT("FPS %.2f"), gf_term_get_framerate(m_term, 0)); - m_pStatusbar->SetStatusText(str, 1); - return; - } -#ifdef __WXGTK__ - if (m_bGrabbed) { - u32 now = gf_sys_clock() - m_last_grab_time; - if (now>200) { - m_bGrabbed = 0; - Double res = (Double) m_last_grab_pos; - res /= 1000; - res *= m_duration; - if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) { - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); - m_bToReset = 0; - } - gf_term_play_from_time(m_term, (u32) res, 0); - return; - } - } -#endif - - if (!m_bGrabbed) { - if ((now >= m_duration + 500) && gf_term_get_option(m_term, GF_OPT_IS_FINISHED)) { - m_pPlayList->PlayNext(); - } else { - Double val = now * 1000; - val /= m_duration; - m_pProg->SetValue((val<=1000) ? (u32) val : 1000); - - if (0) { - str = format_time(m_duration-now, 1000); - } else { - str = format_time(now, 1000); - } - m_pStatusbar->SetStatusText(str); - str = wxString::Format(wxT("FPS %.2f"), gf_term_get_framerate(m_term, 0)); - m_pStatusbar->SetStatusText(str, 1); - } - } -} - -void wxOsmo4Frame::ConnectAcknowledged(Bool bOk) -{ - if (bOk) { - m_pTimer->Start(RTI_REFRESH_MS, 0); - m_connected = 1; - m_bToReset = 0; - UpdatePlay(); - BuildChapterList(0); - } else { - BuildChapterList(1); - if (!m_connected) { - UpdatePlay(); - m_pTimer->Stop(); - //m_pProg->Enable(0); - } - } -} - -void wxOsmo4Frame::OnFilePlay(wxCommandEvent & WXUNUSED(event)) -{ - wxCommandEvent evt; - if (m_connected) { - if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) { - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); - if (m_bToReset) { - m_pTimer->Start(100, 0); - gf_term_play_from_time(m_term, 0, 0); - } - m_bToReset = 0; - UpdatePlay(); - } else { - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); - UpdatePlay(); - } - } else { - m_pPlayList->Play(); - } -} - -void wxOsmo4Frame::OnFileStep(wxCommandEvent & WXUNUSED(event)) -{ - wxCommandEvent evt; - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); - UpdatePlay(); -} - -void wxOsmo4Frame::OnFileStop(wxCommandEvent &WXUNUSED(event)) -{ - Stop(); -} - -void wxOsmo4Frame::Stop() -{ - if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) { - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); - } - m_bToReset = 1; - m_pTimer->Stop(); - m_pProg->SetValue(0); - UpdatePlay(); -} - -void wxOsmo4Frame::OnSlide(wxScrollEvent &event) -{ - if (!m_duration) return; - - /*wxSlider on GTK is buggy, so track a release timeout*/ -#ifdef __WXGTK__ - m_last_grab_time = gf_sys_clock(); - m_bGrabbed = 1; - m_last_grab_pos = event.GetPosition(); - Double now = (Double) m_last_grab_pos; - now /= 1000; - now *= m_duration; - wxString str = format_time((u32) (now), 1000); - m_pStatusbar->SetStatusText(str); - if (!m_pTimer->IsRunning()) m_pTimer->Start(100, 0); -#else - s32 type = event.GetEventType(); - if (type == wxEVT_SCROLL_THUMBTRACK) { - m_bGrabbed = 1; - Double now = (Double) event.GetPosition(); - now /= 1000; - now *= m_duration; - wxString str = format_time((u32) (now), 1000); - m_pStatusbar->SetStatusText(str); - } - else if (m_bGrabbed){ - m_bGrabbed = 0; - Double res = (Double) m_pProg->GetValue(); - res /= 1000; - res *= m_duration; - if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) { - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); - m_bToReset = 0; - if (!m_pTimer->IsRunning()) m_pTimer->Start(100, 0); - } - gf_term_play_from_time(m_term, (u32) res, 0); - } -#endif -} - - -void wxOsmo4Frame::BuildViewList() -{ - if (!vp_list || !m_connected) return; - - while (vp_list->GetMenuItemCount()) { - wxMenuItem* it = vp_list->FindItemByPosition(0); - vp_list->Delete(it); - } - - s32 id = ID_VIEWPOINT_FIRST; - nb_viewpoints = 0; - while (1) { - const char *szName; - Bool bound; - GF_Err e = gf_term_get_viewpoint(m_term, nb_viewpoints+1, &szName, &bound); - if (e) break; - if (szName) { - vp_list->AppendCheckItem(id+nb_viewpoints, wxString(szName, wxConvUTF8) ); - } else { - vp_list->AppendCheckItem(id+nb_viewpoints, wxString::Format(wxT("Viewpoint #%d"), nb_viewpoints+1) ); - } - nb_viewpoints++; - } -} - -void wxOsmo4Frame::OnViewport(wxCommandEvent & event) -{ - u32 ID = event.GetId() - ID_VIEWPOINT_FIRST; - gf_term_set_viewpoint(m_term, ID+1, NULL); -} - -void wxOsmo4Frame::OnUpdateViewport(wxUpdateUIEvent & event) -{ - u32 ID = event.GetId() - ID_VIEWPOINT_FIRST; - const char *szName; - Bool bound; - gf_term_get_viewpoint(m_term, ID+1, &szName, &bound); - event.Enable(1); - if (bound) event.Check(1); -} - -void wxOsmo4Frame::OnNavigate(wxCommandEvent & event) -{ - switch (event.GetId()) { - case ID_NAVIGATE_NONE: gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE); break; - case ID_NAVIGATE_WALK: gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_WALK); break; - case ID_NAVIGATE_FLY: gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_FLY); break; - case ID_NAVIGATE_EXAMINE: gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE); break; - case ID_NAVIGATE_PAN: gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_PAN); break; - case ID_NAVIGATE_SLIDE: gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE); break; - case ID_NAVIGATE_ORBIT: gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_ORBIT); break; - case ID_NAVIGATE_GAME: gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_GAME); break; - } -} -void wxOsmo4Frame::OnNavigateReset(wxCommandEvent & WXUNUSED(event)) -{ - gf_term_set_option(m_term, GF_OPT_NAVIGATION_TYPE, 0); -} -void wxOsmo4Frame::OnUpdateNavigation(wxUpdateUIEvent & event) -{ - u32 ID = event.GetId(); - event.Enable(0); - if (!m_connected) return; - u32 type = gf_term_get_option(m_term, GF_OPT_NAVIGATION_TYPE); - bool enable = type ? 1 : 0; - - u32 mode = gf_term_get_option(m_term, GF_OPT_NAVIGATION); - /*common 2D/3D modes*/ - if (ID==ID_NAVIGATE_NONE) { event.Enable(enable); event.Check(mode ? 0 : 1); } - else if (ID==ID_NAVIGATE_EXAMINE) { event.Enable(enable); event.Check((mode==GF_NAVIGATE_EXAMINE) ? 1 : 0); } - else if (ID==ID_NAVIGATE_SLIDE) { event.Enable(enable); event.Check((mode==GF_NAVIGATE_SLIDE) ? 1 : 0); } - - if (type==GF_NAVIGATE_TYPE_2D) return; - event.Enable(enable); - if (ID==ID_NAVIGATE_WALK) event.Check((mode==GF_NAVIGATE_WALK) ? 1 : 0); - else if (ID==ID_NAVIGATE_FLY) event.Check((mode==GF_NAVIGATE_FLY) ? 1 : 0); - else if (ID==ID_NAVIGATE_PAN) event.Check((mode==GF_NAVIGATE_PAN) ? 1 : 0); - else if (ID==ID_NAVIGATE_ORBIT) event.Check((mode==GF_NAVIGATE_ORBIT) ? 1 : 0); - else if (ID==ID_NAVIGATE_GAME) event.Check((mode==GF_NAVIGATE_GAME) ? 1 : 0); -} - -void wxOsmo4Frame::OnRenderSwitch(wxCommandEvent &WXUNUSED(event)) -{ - const char *opt = gf_cfg_get_key(m_user.config, "Compositor", "ForceOpenGL"); - Bool use_gl = (opt && !stricmp(opt, "yes")) ? 1 : 0; - gf_cfg_set_key(m_user.config, "Compositor", "ForceOpenGL", use_gl ? "no" : "yes"); - - gf_term_set_option(m_term, GF_OPT_USE_OPENGL, !use_gl); - - UpdateRenderSwitch(); -} - -void wxOsmo4Frame::UpdateRenderSwitch() -{ - const char *opt = gf_cfg_get_key(m_user.config, "Compositor", "ForceOpenGL"); - m_pToolBar->RemoveTool(SWITCH_RENDER); - if (opt && !stricmp(opt, "yes")) - m_pToolBar->InsertTool(12, SWITCH_RENDER, *m_pSW2D, wxNullBitmap, FALSE, NULL, wxT("2D Rasterizer")); - else - m_pToolBar->InsertTool(12, SWITCH_RENDER, *m_pSW3D, wxNullBitmap, FALSE, NULL, wxT("OpenGL Rendering")); - -#ifdef WIN32 - /*there's a display bug with the menubtn, remove and reinsert*/ - m_pToolBar->RemoveTool(FILE_PREV); - m_pToolBar->RemoveTool(FILE_NEXT); - m_pToolBar->InsertControl(2, m_pPrevBut); - m_pToolBar->InsertControl(3, m_pNextBut); -#endif - m_pToolBar->Realize(); -} - -void wxOsmo4Frame::UpdatePlay() -{ - m_pToolBar->RemoveTool(FILE_PLAY); - if (m_connected) { - if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) - m_pToolBar->InsertTool(5, FILE_PLAY, *m_pPlay, wxNullBitmap, FALSE, NULL, wxT("Pause File")); - else - m_pToolBar->InsertTool(5, FILE_PLAY, *m_pPause, wxNullBitmap, FALSE, NULL, wxT("Play File")); - } else { - m_pToolBar->InsertTool(5, FILE_PLAY, *m_pPlay, wxNullBitmap, FALSE, NULL, wxT("Pause File")); - } - -#ifdef WIN32 - /*there's a display bug with the menubtn, remove and reinsert*/ - m_pToolBar->RemoveTool(FILE_PREV); - m_pToolBar->RemoveTool(FILE_NEXT); - m_pToolBar->InsertControl(2, m_pPrevBut); - m_pToolBar->InsertControl(3, m_pNextBut); -#endif - m_pToolBar->Realize(); -} - -void wxOsmo4Frame::OnCollide(wxCommandEvent & event) -{ - u32 ID = event.GetId(); - if (ID==ID_COLLIDE_NONE) gf_term_set_option(m_term, GF_OPT_COLLISION, GF_COLLISION_NONE); - else if (ID==ID_COLLIDE_REG) gf_term_set_option(m_term, GF_OPT_COLLISION, GF_COLLISION_NORMAL); - else if (ID==ID_COLLIDE_DISP) gf_term_set_option(m_term, GF_OPT_COLLISION, GF_COLLISION_DISPLACEMENT); -} -void wxOsmo4Frame::OnUpdateCollide(wxUpdateUIEvent & event) -{ - u32 ID = event.GetId(); - event.Enable(0); - if (!m_connected) return; - event.Enable(1); - u32 mode = gf_term_get_option(m_term, GF_OPT_COLLISION); - if (ID==ID_COLLIDE_NONE) { event.Check((mode==GF_COLLISION_NONE) ? 1 : 0); } - else if (ID==ID_COLLIDE_REG) { event.Check((mode==GF_COLLISION_NORMAL) ? 1 : 0); } - else if (ID==ID_COLLIDE_DISP) { event.Check((mode==GF_COLLISION_DISPLACEMENT) ? 1 : 0); } -} - -void wxOsmo4Frame::OnHeadlight(wxCommandEvent &WXUNUSED(event)) -{ - Bool val = !gf_term_get_option(m_term, GF_OPT_HEADLIGHT); - gf_term_set_option(m_term, GF_OPT_HEADLIGHT, val); -} -void wxOsmo4Frame::OnUpdateHeadlight(wxUpdateUIEvent & event) -{ - event.Enable(0); - if (!m_connected) return; - u32 type = gf_term_get_option(m_term, GF_OPT_NAVIGATION_TYPE); - if (type!=GF_NAVIGATE_TYPE_3D) return; - - event.Enable(1); - event.Check(gf_term_get_option(m_term, GF_OPT_HEADLIGHT) ? 1 : 0); -} -void wxOsmo4Frame::OnGravity(wxCommandEvent & WXUNUSED(event)) -{ - Bool val = gf_term_get_option(m_term, GF_OPT_GRAVITY) ? 0 : 1; - gf_term_set_option(m_term, GF_OPT_GRAVITY, val); -} -void wxOsmo4Frame::OnUpdateGravity(wxUpdateUIEvent & event) -{ - event.Enable(0); - if (!m_connected) return; - u32 type = gf_term_get_option(m_term, GF_OPT_NAVIGATION_TYPE); - if (type!=GF_NAVIGATE_TYPE_3D) return; - type = gf_term_get_option(m_term, GF_OPT_NAVIGATION); - if (type != GF_NAVIGATE_WALK) return; - event.Enable(1); - event.Check(gf_term_get_option(m_term, GF_OPT_GRAVITY) ? 1 : 0); -} - - -BEGIN_EVENT_TABLE(wxMyComboBox, wxComboBox) - EVT_KEY_UP(wxMyComboBox::OnKeyUp) -END_EVENT_TABLE() - -void wxMyComboBox::OnKeyUp(wxKeyEvent &event) -{ - if (event.GetKeyCode()==WXK_RETURN) { - event.Skip(); - wxCommandEvent evt; - evt.SetEventType(wxEVT_COMMAND_COMBOBOX_SELECTED); - evt.SetEventObject(this); - evt.SetId(GetId()); - GetParent()->AddPendingEvent(evt); - } -} - - -void wxOsmo4Frame::ReloadURLs() -{ - const char *sOpt; - u32 i=0; - - m_Address->Clear(); - while (1) { - sOpt = gf_cfg_get_key_name(m_user.config, "RecentFiles", i); - if (!sOpt) break; - m_Address->Append(wxString(sOpt, wxConvUTF8) ); - i++; - } -} - -void wxOsmo4Frame::SelectionReady() -{ - wxString urlVal = m_Address->GetValue(); - if (urlVal.Find(wxT("://"))>0) { - UpdateLastFiles(m_user.config, urlVal.mb_str(wxConvUTF8)); - ReloadURLs(); - } - m_pPlayList->Truncate(); - m_pPlayList->QueueURL(urlVal); - m_pPlayList->RefreshList(); - m_pPlayList->PlayNext(); -} - -void wxOsmo4Frame::OnURLSelect(wxCommandEvent &WXUNUSED(event)) -{ - SelectionReady(); -} - -void wxOsmo4Frame::OnPlaylist(wxCommandEvent &WXUNUSED(event)) -{ - assert(m_pPlayList); - m_pPlayList->Show(m_pPlayList->IsShown() ? 0 : 1); -} - -void wxOsmo4Frame::OnUpdatePlayList(wxUpdateUIEvent & event) -{ - event.Enable(1); - event.Check(m_pPlayList->IsShown() ? 1 : 0); -} - -void wxOsmo4Frame::OnFilePrevOpen(wxNotifyEvent & event) -{ - u32 count = gf_list_count(m_pPlayList->m_entries); - u32 start = m_pPlayList->m_cur_entry - 1; - wxMenu *popup = new wxMenu(); - - for (u32 i=0; i<10; i++) { - if (i > start) break; - if (start - i >= count) break; - PLEntry *ple = (PLEntry *) gf_list_get(m_pPlayList->m_entries, start - i); - popup->Append(ID_NAV_PREV_0 + i, wxString(ple->m_disp_name, wxConvUTF8) ); - } - m_pPrevBut->AssignMenu(popup); -} - -void wxOsmo4Frame::OnFileNextOpen(wxNotifyEvent & event) -{ - u32 count = gf_list_count(m_pPlayList->m_entries); - wxMenu *popup = new wxMenu(); - u32 start = m_pPlayList->m_cur_entry + 1; - for (u32 i=0; i<10; i++) { - if (start + i >= count) break; - PLEntry *ple = (PLEntry *) gf_list_get(m_pPlayList->m_entries, start + i); - popup->Append(ID_NAV_NEXT_0 + i, wxString(ple->m_disp_name, wxConvUTF8) ); - } - m_pNextBut->AssignMenu(popup); -} - -void wxOsmo4Frame::OnNavPrev(wxCommandEvent &WXUNUSED(event)) -{ - if (m_pPlayList->m_cur_entry<=0) return; - m_pPlayList->PlayPrev(); -} -void wxOsmo4Frame::OnUpdateNavPrev(wxUpdateUIEvent & event) -{ - if (m_pPlayList->m_cur_entry<=0) event.Enable(0); - else event.Enable(TRUE); -} -void wxOsmo4Frame::OnNavPrevMenu(wxCommandEvent &event) -{ - u32 ID = event.GetId() - ID_NAV_PREV_0; - s32 prev = m_pPlayList->m_cur_entry - ID; - if (prev>=0) { - m_pPlayList->m_cur_entry = prev; - m_pPlayList->PlayPrev(); - } -} -void wxOsmo4Frame::OnNavNext(wxCommandEvent &WXUNUSED(event)) -{ - /*don't play if last could trigger playlist loop*/ - if ((m_pPlayList->m_cur_entry<0) || (gf_list_count(m_pPlayList->m_entries) == 1 + (u32) m_pPlayList->m_cur_entry)) return; - m_pPlayList->PlayNext(); -} -void wxOsmo4Frame::OnUpdateNavNext(wxUpdateUIEvent & event) -{ - if (m_pPlayList->m_cur_entry<0) event.Enable(0); - else if ((u32) m_pPlayList->m_cur_entry + 1 == gf_list_count(m_pPlayList->m_entries) ) event.Enable(0); - else event.Enable(1); -} - -void wxOsmo4Frame::OnNavNextMenu(wxCommandEvent &event) -{ - u32 ID = event.GetId() - ID_NAV_NEXT_0; - s32 next = m_pPlayList->m_cur_entry + ID; - if (next < (s32) gf_list_count(m_pPlayList->m_entries) ) { - m_pPlayList->m_cur_entry = next; - m_pPlayList->PlayNext(); - } -} - -void wxOsmo4Frame::OnClearNav(wxCommandEvent &WXUNUSED(event)) -{ - m_pPlayList->ClearButPlaying(); -} - - -void wxOsmo4Frame::BuildStreamList(Bool reset_only) -{ - u32 nb_subs; - wxMenu *pMenu; - - pMenu = sel_menu->FindItemByPosition(0)->GetSubMenu(); - while (pMenu->GetMenuItemCount()) { - wxMenuItem* it = pMenu->FindItemByPosition(0); - pMenu->Delete(it); - } - pMenu = sel_menu->FindItemByPosition(1)->GetSubMenu(); - while (pMenu->GetMenuItemCount()) { - wxMenuItem* it = pMenu->FindItemByPosition(0); - pMenu->Delete(it); - } - pMenu = sel_menu->FindItemByPosition(2)->GetSubMenu(); - while (pMenu->GetMenuItemCount()) { - wxMenuItem* it = pMenu->FindItemByPosition(0); - pMenu->Delete(it); - } - - if (reset_only) { - m_bFirstStreamListBuild = 1; - return; - } - - if (!gf_term_get_option(m_term, GF_OPT_CAN_SELECT_STREAMS)) return; - - nb_subs = 0; - GF_ObjectManager *root_od = gf_term_get_root_object(m_term); - if (!root_od) return; - u32 count = gf_term_get_object_count(m_term, root_od); - - for (u32 i=0; iFindItemByPosition(0)->GetSubMenu(); - if (!info.owns_service) sprintf(szLabel, "Audio #"LLU, (u64)pMenu->GetMenuItemCount() + 1); - pMenu->AppendCheckItem(ID_SELSTREAM_0 +i, wxString(szLabel, wxConvUTF8)); - break; - case GF_STREAM_VISUAL: - pMenu = sel_menu->FindItemByPosition(1)->GetSubMenu(); - if (!info.owns_service) sprintf(szLabel, "Video #"LLU, (u64)pMenu->GetMenuItemCount() + 1); - pMenu->AppendCheckItem(ID_SELSTREAM_0 +i, wxString(szLabel, wxConvUTF8)); - break; - case GF_STREAM_TEXT: - nb_subs ++; - pMenu = sel_menu->FindItemByPosition(2)->GetSubMenu(); - if (!info.owns_service) sprintf(szLabel, "Subtitle #"LLU, (u64)pMenu->GetMenuItemCount() + 1); - pMenu->AppendCheckItem(ID_SELSTREAM_0 +i, wxString(szLabel, wxConvUTF8)); - break; - } - } - if (m_bFirstStreamListBuild) { - m_bFirstStreamListBuild = 0; - if (!nb_subs && m_lookforsubs) LookForSubtitles(); - } -} - -void wxOsmo4Frame::OnStreamSel(wxCommandEvent & event) -{ - GF_ObjectManager *root_od = gf_term_get_root_object(m_term); - if (!root_od) return; - u32 ID = event.GetId() - ID_SELSTREAM_0; - GF_ObjectManager *odm = gf_term_get_object(m_term, root_od, ID); - gf_term_select_object(m_term, odm); -} - -void wxOsmo4Frame::OnUpdateStreamSel(wxUpdateUIEvent & event) -{ - GF_ObjectManager *root_od = gf_term_get_root_object(m_term); - if (!root_od) return; - u32 ID = event.GetId() - ID_SELSTREAM_0; - - GF_ObjectManager *odm = gf_term_get_object(m_term, root_od, ID); - if (!odm) return; - - GF_MediaInfo info; - gf_term_get_object_info(m_term, odm, &info); - event.Enable(1); - event.Check(info.status ? 1 : 0); -} - -void wxOsmo4Frame::OnUpdateStreamMenu(wxUpdateUIEvent & event) -{ - if (!m_connected || !gf_term_get_option(m_term, GF_OPT_CAN_SELECT_STREAMS)) { - event.Enable(0); - } else { - event.Enable(1); - } -} - -void wxOsmo4Frame::OnAddSub(wxCommandEvent &WXUNUSED(event)) -{ - wxFileDialog dlg(this, wxT("Add Subtitle"), wxT(""), wxT(""), wxT("All Subtitles|*.srt;*.ttxt|SRT Subtitles|*.srt|3GPP TimedText|*.ttxt|"), wxOPEN | wxCHANGE_DIR /* | wxHIDE_READONLY*/); - - if (dlg.ShowModal() == wxID_OK) { - AddSubtitle(dlg.GetPath().mb_str(wxConvUTF8), 1); - } - -} - -void wxOsmo4Frame::AddSubtitle(const char *fileName, Bool auto_play) -{ - gf_term_add_object(m_term, fileName, auto_play); -} - -static Bool subs_enum_dir_item(void *cbck, char *item_name, char *item_path) -{ - wxOsmo4Frame *_this = (wxOsmo4Frame*)cbck; - _this->AddSubtitle(item_path, 0); - return 0; -} - -void wxOsmo4Frame::LookForSubtitles() -{ - char dir[GF_MAX_PATH]; - const char *url = m_pPlayList->GetURL().mb_str(wxConvUTF8); - strcpy(dir, url); - char *sep = strrchr(dir, '\\'); - if (!sep) strcpy(dir, ::wxGetCwd().mb_str(wxConvUTF8)); - else sep[0] = 0; - - gf_enum_directory(dir, 0, subs_enum_dir_item, this, "ttxt;srt"); -} - -void wxOsmo4Frame::OnCacheEnable(wxCommandEvent &WXUNUSED(event)) -{ - u32 state = gf_term_get_option(m_term, GF_OPT_MEDIA_CACHE); - if (state==GF_MEDIA_CACHE_DISABLED) { - gf_term_set_option(m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_ENABLED); - } else if (state==GF_MEDIA_CACHE_DISABLED) { - gf_term_set_option(m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); - } -} - -void wxOsmo4Frame::OnCacheStop(wxCommandEvent &WXUNUSED(event)) -{ - gf_term_set_option(m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); -} - -void wxOsmo4Frame::OnCacheAbort(wxCommandEvent &WXUNUSED(event)) -{ - gf_term_set_option(m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISCARD); -} - -void wxOsmo4Frame::OnUpdateCacheEnable(wxUpdateUIEvent & event) -{ - u32 state = gf_term_get_option(m_term, GF_OPT_MEDIA_CACHE); - switch (state) { - case GF_MEDIA_CACHE_ENABLED: - event.Enable(1); - event.SetText(wxT("Enabled")); - break; - case GF_MEDIA_CACHE_RUNNING: - event.SetText(wxT("Running")); - event.Enable(0); - break; - case GF_MEDIA_CACHE_DISABLED: - event.SetText(wxT("Disabled")); - break; - } -} - -void wxOsmo4Frame::OnUpdateCacheAbort(wxUpdateUIEvent & event) -{ - u32 state = gf_term_get_option(m_term, GF_OPT_MEDIA_CACHE); - event.Enable( (state==GF_MEDIA_CACHE_RUNNING) ? 1 : 0); -} - - - -void wxOsmo4Frame::BuildChapterList(Bool reset_only) -{ - GF_MediaInfo odi; - - while (chap_menu->GetMenuItemCount()) { - wxMenuItem* it = chap_menu->FindItemByPosition(0); - chap_menu->Delete(it); - } - if (m_chapters_start) gf_free(m_chapters_start); - m_chapters_start = NULL; - m_num_chapters = 0; - if (reset_only) return; - - GF_ObjectManager *root_od = gf_term_get_root_object(m_term); - if (!root_od) return; - if (gf_term_get_object_info(m_term, root_od, &odi) != GF_OK) return; - - u32 count = gf_list_count(odi.od->OCIDescriptors); - m_num_chapters = 0; - for (u32 i=0; iOCIDescriptors, i); - if (seg->tag != GF_ODF_SEGMENT_TAG) continue; - - if (seg->SegmentName && strlen((const char *)seg->SegmentName)) { - strcpy(szLabel, (const char *) seg->SegmentName); - } else { - sprintf(szLabel, "Chapter %02d", m_num_chapters+1); - } - chap_menu->AppendCheckItem(ID_SETCHAP_FIRST + m_num_chapters, wxString(szLabel, wxConvUTF8)); - - m_chapters_start = (Double *) gf_realloc(m_chapters_start, sizeof(Double)*(m_num_chapters+1)); - m_chapters_start[m_num_chapters] = seg->startTime; - m_num_chapters++; - } - - /*get any service info*/ - NetInfoCommand com; - if (!m_bStartupFile && gf_term_get_service_info(m_term, root_od, &com) == GF_OK) { - wxString title = wxT(""); - if (com.track_info) { title.Format(wxT("%02d "), (u32) (com.track_info>>16) ); } - if (com.artist) { title.Append(wxString(com.artist, wxConvUTF8)); title += wxT(" "); } - if (com.name) { title.Append(wxString(com.name, wxConvUTF8)); title += wxT(" "); } - if (com.album) { title += wxT("("); title.Append(wxString(com.album, wxConvUTF8)); title += wxT(")"); } - - if (title.length()) SetTitle(title); - } - -} - -void wxOsmo4Frame::OnChapterSel(wxCommandEvent & event) -{ - GF_ObjectManager *root_od = gf_term_get_root_object(m_term); - if (!root_od) return; - u32 ID = event.GetId() - ID_SETCHAP_FIRST; - gf_term_play_from_time(m_term, (u32) (1000*m_chapters_start[ID]), 0); -} - -void wxOsmo4Frame::OnUpdateChapterSel(wxUpdateUIEvent & event) -{ - Double now; - Bool is_current; - u32 ID = event.GetId() - ID_SETCHAP_FIRST; - - now = gf_term_get_time_in_ms(m_term); - now /= 1000; - - is_current = 0; - if (m_chapters_start[ID]<=now) { - if (ID+1now) is_current = 1; - } else { - is_current = 1; - } - } - event.Enable(1); - event.Check(is_current ? 1 : 0); -} - -void wxOsmo4Frame::OnUpdateChapterMenu(wxUpdateUIEvent & event) -{ - if (!m_connected || !m_num_chapters) { - event.Enable(0); - } else { - event.Enable(1); - } -} - -void wxOsmo4Frame::OnFileCopy(wxCommandEvent &event) -{ - const char *text = gf_term_get_text_selection(m_term, 0); - if (!text) return; - if (!wxTheClipboard->Open()) return; - - wxTheClipboard->SetData( new wxTextDataObject( wxString(text, wxConvUTF8)) ); - wxTheClipboard->Close(); -} - -void wxOsmo4Frame::OnUpdateFileCopy(wxUpdateUIEvent &event) -{ - if (gf_term_get_text_selection(m_term, 1)!=NULL) { - event.Enable(1); - } else { - event.Enable(0); - } -} - -void wxOsmo4Frame::OnFilePaste(wxCommandEvent &event) -{ - if (!wxTheClipboard->Open()) return; - if (wxTheClipboard->IsSupported( wxDF_TEXT )) { - wxTextDataObject data; - wxTheClipboard->GetData(data); - gf_term_paste_text(m_term, data.GetText().mb_str(wxConvUTF8), 0); - } - wxTheClipboard->Close(); -} - -void wxOsmo4Frame::OnUpdateFilePaste(wxUpdateUIEvent &event) -{ - Bool ok = 0; - if (wxTheClipboard->Open()) { - if (wxTheClipboard->IsSupported( wxDF_TEXT )) { - if (gf_term_paste_text(m_term, NULL, 1)==GF_OK) { - ok = 1; - } - } - wxTheClipboard->Close(); - } - event.Enable(ok ? 1 : 0); -} - diff --git a/applications/osmo4_wx/wxOsmo4.h b/applications/osmo4_wx/wxOsmo4.h deleted file mode 100644 index 6c2b463..0000000 --- a/applications/osmo4_wx/wxOsmo4.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Osmo4 wxWidgets GUI - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#ifndef _WXOSMO4_H -#define _WXOSMO4_H - -/* -we need to force X to work in sync mode when we use embedded view... -include first to avoid Bool type redef between X11 and gpac -*/ -#ifdef __WXGTK__ -#include -#endif - -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#endif - -#include -#include -#include -#include "menubtn.h" - -/*include gpac AFTER wx in case we override malloc/realloc/free for mem tracking*/ -#include -#include - -class wxOsmo4App : public wxApp -{ -public: - virtual bool OnInit(); -}; - -DECLARE_APP(wxOsmo4App) - -class wxOsmo4Frame; -class wxPlaylist; - -class GPACLogs : public wxLogWindow { -public: - GPACLogs(wxFrame *parent) : wxLogWindow(parent, wxT("GPAC Logs"), FALSE, FALSE) { - m_pMain = (wxOsmo4Frame *) parent; - } - virtual bool OnFrameClose(wxFrame *frame); - -private: - wxOsmo4Frame *m_pMain; -}; - -#define MAX_VIEWPOINTS 50 - -// Menu commands -enum -{ - GWX_FILE_OPEN = wxID_HIGHEST, - GWX_FILE_OPEN_URL, - FILE_RELOAD, - FILE_RELOAD_CONFIG, - FILE_PLAY, - FILE_STEP, - FILE_STOP, - FILE_PREV, - FILE_NEXT, - FILE_PROPERTIES, - FILE_COPY, - FILE_PASTE, - TERM_RELOAD, - FILE_QUIT, - VIEW_FULLSCREEN, - VIEW_ORIGINAL, - VIEW_AR_KEEP, - VIEW_AR_FILL, - VIEW_AR_43, - VIEW_AR_169, - VIEW_OPTIONS, - VIEW_LOGS, - VIEW_RTI, - VIEW_PLAYLIST, - SWITCH_RENDER, - APP_SHORTCUTS, - APP_NAV_KEYS, - APP_ABOUT, - ID_ADDRESS, - ID_URL_GO, - ID_ABOUT_CLOSE, - ID_CLEAR_NAV, - ID_STREAM_MENU, - ID_CHAPTER_MENU, - ID_ADD_SUB, - - ID_MCACHE_ENABLE, - ID_MCACHE_STOP, - ID_MCACHE_ABORT, - - ID_CTRL_TIMER, - ID_SLIDER, - - ID_TREE_VIEW, - ID_OD_TIMER, - ID_VIEW_SG, - ID_VIEW_WI, - ID_VIEW_SEL, - - - ID_HEADLIGHT, - ID_NAVIGATE_NONE, - ID_NAVIGATE_WALK, - ID_NAVIGATE_FLY, - ID_NAVIGATE_EXAMINE, - ID_NAVIGATE_SLIDE, - ID_NAVIGATE_PAN, - ID_NAVIGATE_ORBIT, - ID_NAVIGATE_GAME, - ID_NAVIGATE_RESET, - - ID_COLLIDE_NONE, - ID_COLLIDE_REG, - ID_COLLIDE_DISP, - ID_GRAVITY, - - ID_PL_OPEN, - ID_PL_SAVE, - ID_PL_ADD_FILE, - ID_PL_ADD_URL, - ID_PL_ADD_DIR, - ID_PL_ADD_DIR_REC, - ID_PL_REM_FILE, - ID_PL_REM_ALL, - ID_PL_REM_DEAD, - ID_PL_UP, - ID_PL_DOWN, - ID_PL_RANDOMIZE, - ID_PL_REVERSE, - ID_PL_SEL_REV, - ID_PL_SORT_TITLE, - ID_PL_SORT_FILE, - ID_PL_SORT_DUR, - ID_PL_PLAY, - - - /*reserve IDs for viewpoint menu*/ - ID_VIEWPOINT_FIRST, - ID_VIEWPOINT_LAST = ID_VIEWPOINT_FIRST + MAX_VIEWPOINTS, - - /*reserve IDs for navigation menus*/ - ID_NAV_PREV_0, - ID_NAV_PREV_9 = ID_NAV_PREV_0 + 10, - ID_NAV_NEXT_0, - ID_NAV_NEXT_9 = ID_NAV_NEXT_0 + 10, - /*reserve IDs for stream selection menus*/ - ID_SELSTREAM_0, - ID_SELSTREAM_9 = ID_SELSTREAM_0 + 10, - - /*reserve IDs for chapter selection menus*/ - ID_SETCHAP_FIRST, - ID_SETCHAP_LAST = ID_SELSTREAM_0 + 200, -}; - -wxString get_pref_browser(GF_Config *cfg); - -class wxGPACEvent : public wxEvent -{ -public: - wxGPACEvent( wxWindow* win = (wxWindow*) NULL ); - void CopyObject( wxObject& obj ) const; - virtual wxEvent *Clone() const; - - wxString to_url; - GF_Event gpac_evt; - - DECLARE_DYNAMIC_CLASS(wxGPACEvent) -}; -typedef void (wxEvtHandler::*GPACEventFunction)(wxGPACEvent&); -DEFINE_EVENT_TYPE(GPAC_EVENT) - -#define EVT_GPACEVENT(func) DECLARE_EVENT_TABLE_ENTRY(GPAC_EVENT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (GPACEventFunction) & func, (wxObject*) NULL), - -class OpenURLDlg : public wxDialog { -public: - OpenURLDlg(wxWindow *parent, GF_Config *cfg); - wxString m_urlVal; -private: - wxButton *m_go; - wxComboBox *m_url; - GF_Config *m_cfg; - void OnGo(wxCommandEvent& event); - DECLARE_EVENT_TABLE() -}; - -class wxMyComboBox : public wxComboBox -{ -public: - wxMyComboBox(wxWindow* parent, wxWindowID id, const wxString& value = wxT(""), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize) - : wxComboBox(parent, id, value, pos, size, 0, NULL, wxCB_DROPDOWN) - {} - -private: - DECLARE_EVENT_TABLE() - - void OnKeyUp(wxKeyEvent &event); -}; - -class wxOsmo4Frame : public wxFrame { -public: - wxOsmo4Frame(); - virtual ~wxOsmo4Frame(); - - char szAppPath[GF_MAX_PATH]; - - u32 m_duration; - wxString the_next_url; - GF_Terminal *m_term; - GF_User m_user; - Bool m_connected, m_can_seek, m_console_off, m_loop, m_lookforsubs; - - void DoConnect(); - - void ConnectAcknowledged(Bool bOk); - void SetStatus(wxString str); - - void OnFilePlay(wxCommandEvent &event); - void OnFileStep(wxCommandEvent &event); - void OnFileStop(wxCommandEvent &event); - wxString GetFileFilter(); - - void BuildViewList(); - void BuildStreamList(Bool reset_only); - void BuildChapterList(Bool reset_only); - - void AddSubtitle(const char *fileName, Bool auto_play); - - wxWindow *m_pView; - -#ifdef __WXGTK__ - u32 m_last_grab_time, m_last_grab_pos; - wxWindow *m_pVisual; -#endif - wxSlider *m_pProg; - wxPlaylist *m_pPlayList; - - void DoLayout(u32 v_width = 0, u32 v_height = 0); - s32 m_last_prog; - - FILE *m_logs; - u32 m_log_level, m_log_tools; - u32 m_LastStatusTime; - -protected: - -private: - DECLARE_EVENT_TABLE() - - void OnCloseApp(wxCloseEvent &event); - void OnSize(wxSizeEvent &event); - - void OnFileOpen(wxCommandEvent &event); - void OnFileOpenURL(wxCommandEvent &event); - void OnFileReload(wxCommandEvent &event); - void OnFileReloadConfig(wxCommandEvent & event); - void OnFileProperties(wxCommandEvent &event); - void OnFileQuit(wxCommandEvent &event); - void OnFullScreen(wxCommandEvent &event); - void OnOptions(wxCommandEvent &event); - void OnViewARKeep(wxCommandEvent &event); - void OnViewARFill(wxCommandEvent &event); - void OnViewAR169(wxCommandEvent &event); - void OnViewAR43(wxCommandEvent &event); - void OnViewOriginal(wxCommandEvent &event); - void OnPlaylist(wxCommandEvent &event); - void OnShortcuts(wxCommandEvent &event); - void OnNavInfo(wxCommandEvent &event); - void OnAddSub(wxCommandEvent &event); - void OnAbout(wxCommandEvent &event); - Bool LoadTerminal(); - void OnGPACEvent(wxGPACEvent &event); - void OnTimer(wxTimerEvent& event); - void OnSlide(wxScrollEvent &event); - void OnRelease(wxScrollEvent &event); - void OnLogs(wxCommandEvent & event); - void OnRTI(wxCommandEvent & event); - void OnUpdatePlay(wxUpdateUIEvent &event); - void OnUpdateNeedsConnect(wxUpdateUIEvent &event); - void OnUpdateFullScreen(wxUpdateUIEvent &event); - void OnUpdateAR(wxUpdateUIEvent &event); - void OnViewport(wxCommandEvent & event); - void OnUpdateViewport(wxUpdateUIEvent & event); - void OnNavigate(wxCommandEvent & event); - void OnNavigateReset(wxCommandEvent & event); - void OnUpdateNavigation(wxUpdateUIEvent & event); - void OnRenderSwitch(wxCommandEvent &event); - void OnCollide(wxCommandEvent & event); - void OnUpdateCollide(wxUpdateUIEvent & event); - void OnHeadlight(wxCommandEvent & event); - void OnUpdateHeadlight(wxUpdateUIEvent & event); - void OnGravity(wxCommandEvent & event); - void OnUpdateGravity(wxUpdateUIEvent & event); - void OnURLSelect(wxCommandEvent &event); - void OnUpdatePlayList(wxUpdateUIEvent & event); - void OnFilePrevOpen(wxNotifyEvent & event); - void OnFileNextOpen(wxNotifyEvent & event); - void OnNavPrev(wxCommandEvent &event); - void OnUpdateNavPrev(wxUpdateUIEvent & event); - void OnNavPrevMenu(wxCommandEvent &event); - void OnNavNext(wxCommandEvent &event); - void OnUpdateNavNext(wxUpdateUIEvent & event); - void OnNavNextMenu(wxCommandEvent &event); - void OnClearNav(wxCommandEvent &event); - void OnStreamSel(wxCommandEvent &event); - void OnUpdateStreamSel(wxUpdateUIEvent & event); - void OnUpdateStreamMenu(wxUpdateUIEvent & event); - void OnChapterSel(wxCommandEvent &event); - void OnUpdateChapterSel(wxUpdateUIEvent & event); - void OnUpdateChapterMenu(wxUpdateUIEvent & event); - - void SelectionReady(); - void ReloadURLs(); - void LookForSubtitles(); - - void OnCacheEnable(wxCommandEvent &event); - void OnCacheStop(wxCommandEvent &event); - void OnCacheAbort(wxCommandEvent &event); - void OnUpdateCacheEnable(wxUpdateUIEvent & event); - void OnUpdateCacheAbort(wxUpdateUIEvent & event); - - void OnFileCopy(wxCommandEvent &event); - void OnUpdateFileCopy(wxUpdateUIEvent &event); - void OnFilePaste(wxCommandEvent &event); - void OnUpdateFilePaste(wxUpdateUIEvent &event); - - - void CheckVideoOut(); - - wxMenuBar* m_pMenubar; - wxStatusBar* m_pStatusbar; - wxTimer *m_pTimer; - GPACLogs *m_pLogs; - wxBoxSizer *m_pAddBar; - - Bool m_bGrabbed, m_bToReset, m_bFirstStreamListBuild; - wxBitmap *m_pOpenFile, *m_pPrev, *m_pNext, *m_pPlay, *m_pPause, *m_pStep, *m_pStop, *m_pInfo, *m_pConfig, *m_pSW2D, *m_pSW3D; - wxMenuButton *m_pPrevBut, *m_pNextBut; - wxToolBar *m_pToolBar; - wxMyComboBox *m_Address; - - wxMenu *vp_list; - wxMenu *sel_menu; - wxMenu *chap_menu; - void Stop(); - - s32 nb_viewpoints; - - void UpdateRenderSwitch(); - void UpdatePlay(); - - u32 m_orig_width, m_orig_height; - - u32 m_num_chapters; - Double *m_chapters_start; - Bool m_bExternalView, m_bViewRTI, m_bStartupFile; - - void ShowViewWindow(Bool do_show); -}; - - -#endif //_WXOSMO4_H - diff --git a/applications/osmo4_wx/wxOsmo4.rc b/applications/osmo4_wx/wxOsmo4.rc deleted file mode 100644 index 3e839b8..0000000 --- a/applications/osmo4_wx/wxOsmo4.rc +++ /dev/null @@ -1,72 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// French (France) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) -#ifdef _WIN32 -LANGUAGE LANG_FRENCH, SUBLANG_FRENCH -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_OSMO_ICON ICON DISCARDABLE "../../doc/osmo4.ico" -#endif // French (France) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/applications/v4studio/V4CommandPanel.cpp b/applications/v4studio/V4CommandPanel.cpp deleted file mode 100644 index 9bd1703..0000000 --- a/applications/v4studio/V4CommandPanel.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* - V4CommandPanel.cpp - - Panel allowing to choose an action for a given frame in the time line - -*/ - -#include "safe_include.h" - -#include "V4CommandPanel.h" -#include "V4StudioFrame.h" - -#include "V4Node.h" - - - -// !! order matters !!, index will become the command id -// when command has no string, it is not available -// see v4_scenegraph_vrml.h -wxString cmdNames[] = { wxT(""), // GF_SG_SCENE_REPLACE - wxT("Replace Node"), // GF_SG_NODE_REPLACE - wxT("Replace Field"), // GF_SG_FIELD_REPLACE - wxT(""), // GF_SG_INDEXED_REPLACE - wxT(""), // GF_SG_ROUTE_REPLACE - wxT("Delete Node"), // GF_SG_NODE_DELETE - wxT(""), // GF_SG_INDEXED_DELETE - wxT(""), // GF_SG_ROUTE_DELETE - wxT("Insert Node"), // GF_SG_NODE_INSERT - wxT("") // GF_SG_INDEXED_INSERT - // TODO : to complete - }; - - -// Events table -BEGIN_EVENT_TABLE(V4CommandPanel, wxPanel) - EVT_PAINT(V4CommandPanel::OnPaint) - EVT_COMBOBOX(cmbCommandID, V4CommandPanel::OnCommandCombo) - EVT_COMBOBOX(cmbFieldID, V4CommandPanel::OnFieldCombo) - EVT_BUTTON(CreateID, V4CommandPanel::OnCreateCommand) -END_EVENT_TABLE() - - - -// Constructor -V4CommandPanel::V4CommandPanel(V4StudioFrame * parent_) - : wxPanel(parent_, -1), - // tabs - tabs(this, -1), - tabView(&tabs, -1), - tabAdd(&tabs, -1), - - // add Page - cmbCommands(&tabAdd, cmbCommandID, ""), - lblCommands(&tabAdd, -1, "Action :"), - cmbNodes(&tabAdd, -1, ""), - lblNodes(&tabAdd, -1, "Node :"), - cmbFields(&tabAdd ,cmbFieldID, ""), - lblFields(&tabAdd, -1, "Field :"), - txtField(&tabAdd, -1, ""), - btnCreate(&tabAdd, CreateID, "Create"), - - // view Page - cmbListCommands(&tabView, -1), - txtDesc(&tabView, -1), - btnDelete(&tabView, -1, "Delete") -{ - parent = parent_; - - // disposition - - // global - sizerTabs = new wxBoxSizer(wxHORIZONTAL); - sizerTabs->Add(&tabs, 1, wxEXPAND); - - tabs.AddPage(&tabView, "View"); - tabs.AddPage(&tabAdd, "Add"); - - - // Add Page - sizerAdd = new wxBoxSizer(wxVERTICAL); // up = combobox, middle = differs with the command, bottom = buttons - - sizerU = new wxBoxSizer(wxHORIZONTAL); // up - sizerM = new wxBoxSizer(wxVERTICAL); // middle - sizerD = new wxBoxSizer(wxHORIZONTAL); // bottom - - szSelectNode = new wxBoxSizer(wxHORIZONTAL); - szSelectField = new wxBoxSizer(wxHORIZONTAL); - szTxtField = new wxBoxSizer(wxHORIZONTAL); - - sizerAdd->Add(sizerU, 1, wxEXPAND); - sizerAdd->Add(sizerM, 3, wxEXPAND); - sizerAdd->Add(sizerD, 1, wxEXPAND); - - sizerU->Add(&lblCommands, 1, wxEXPAND | wxALL, 5); - sizerU->Add(&cmbCommands, 3, wxEXPAND | wxALL, 2); - - szSelectField->Add(&lblFields, 1, wxEXPAND | wxALL, 5); - szSelectField->Add(&cmbFields, 2, wxEXPAND | wxALL, 2); - - szSelectNode->Add(&lblNodes, 1, wxEXPAND | wxALL, 5); - szSelectNode->Add(&cmbNodes, 2, wxEXPAND | wxALL, 2); - - szTxtField->Add(&txtField, 1, wxEXPAND | wxALL, 5); - - sizerD->Add(&btnCreate, 1, wxEXPAND | wxALL, 3); - - tabAdd.SetSizer(sizerAdd); - - - - // View Page - sizerView = new wxBoxSizer(wxVERTICAL); - sizerUp = new wxBoxSizer(wxHORIZONTAL); - sizerDown = new wxBoxSizer(wxHORIZONTAL); - - sizerView->Add(sizerUp, 0, wxEXPAND); - sizerView->Add(sizerDown, 4, wxEXPAND); - - sizerUp->Add(&cmbListCommands, 2, wxEXPAND | wxALL, 2); - sizerUp->Add(&btnDelete, 1, wxEXPAND | wxALL, 2); - - sizerDown->Add(&txtDesc, 1, wxEXPAND); - - tabView.SetSizer(sizerView); - - - - // global - SetSizer(sizerTabs); - - //Layout(); - - ShowFieldSizer(false); - ShowNodeSizer(false); - txtField.Show(false); -} - -// Destructor -V4CommandPanel::~V4CommandPanel() { - delete szSelectNode; - delete szSelectField; - delete szTxtField; -}; - -/************************/ -/* Events */ -/************************/ - -// OnPaint event -void V4CommandPanel::OnPaint(wxPaintEvent& event) { - wxPaintDC dc(this); - - dc.BeginDrawing(); - - // draws a seperator line on the left border - int w,h; - this->GetSize(&w, &h); - dc.DrawLine(0, 0, 0, h); - - dc.EndDrawing(); -} - - -// OnCommandCombo -- command combo box selection has changed -void V4CommandPanel::OnCommandCombo(wxCommandEvent &event) { - // retrieves the command id - u32 command = (u32) cmbCommands.GetClientData(cmbCommands.GetSelection()); - - // retrieves the current node - GF_Node * node = GetCurrentNode(); - - if (! IsCommandValidForNode(command, node)) { - cmbCommands.SetSelection(-1); - command = (u32) -1; - } - - // shows or hides components - switch (command) { - case GF_SG_FIELD_REPLACE: { - ShowNodeSizer(false); - ShowFieldSizer(true); - break; - } - - case GF_SG_NODE_REPLACE: - case GF_SG_NODE_INSERT: { - ShowFieldSizer(false); - ShowNodeSizer(true); - break; - } - - case GF_SG_NODE_DELETE: - default : { - ShowFieldSizer(false); - ShowNodeSizer(false); - } - } -} - - -// OnFieldCombo -- field combo box selection has changed -void V4CommandPanel::OnFieldCombo(wxCommandEvent &event) { - - // if no selection exits - u32 sel = cmbFields.GetSelection(); - if (sel == wxNOT_FOUND) return; - - - // gets selected node in the timeline - GF_Node * node = GetCurrentNode(); - if (!node) return; - - GF_FieldInfo field; - gf_node_get_field(node, sel, &field); - - // show or hides elements depending on the type of the field we will modify - if ( (field.fieldType == GF_SG_VRML_SFNODE) || (field.fieldType == GF_SG_VRML_MFNODE) ) { - sizerM->Detach(szTxtField); - txtField.Show(false); - ShowNodeSizer(true); - } else { - sizerM->Detach(szTxtField); - sizerM->Add(szTxtField, 2, wxEXPAND); - txtField.Show(true); - } - -} - - -// OnCreateCommand -- creates a command with the option from the UI -void V4CommandPanel::OnCreateCommand(wxCommandEvent &event) { - - // verifies that there is a valid command value on cmbCommands - u32 sel = cmbCommands.GetSelection(); - if (sel == wxNOT_FOUND) return; - - // gets data from the UI - u32 tag = (u32) cmbCommands.GetClientData(sel); - GF_Node * node = GetCurrentNode(); - - // Creates the new command - REQUIRES registering the node - GF_Command * c = gf_sg_command_new(parent->GetV4SceneManager()->GetSceneGraph(), tag); - gf_node_register(node, NULL); - c->node = node; // !! the node have to be registered if command is validated - - bool succeed = false;; - - // performs various initialization depending on the command tag - switch (tag) { - case GF_SG_NODE_REPLACE: { - // TODO : not implemented yet because il would even replace the nodes in the dictionnary - break; - } - - case GF_SG_FIELD_REPLACE: { - // verifies that a valid field is selected - u32 selF = cmbFields.GetSelection(); - if (selF == wxNOT_FOUND) break; - - // gets the field - GF_FieldInfo field; - gf_node_get_field(node, (u32)cmbFields.GetClientData(selF), &field); - - GF_CommandField * cmdField = gf_sg_command_field_new(c); // if failure, will be freed with freeing the command - cmdField->fieldIndex = field.fieldIndex; - cmdField->fieldType = field.fieldType; - - // fills the GF_CommandField structures with data depending on the field type - switch (field.fieldType) { - case GF_SG_VRML_SFNODE: { - // get the node we will use as a replacement - u32 selN = cmbNodes.GetSelection(); - if (selN == wxNOT_FOUND) break; - - cmdField->new_node = (GF_Node *) cmbNodes.GetClientData(selN); - // TODO : why is the 2nd line necessary ? - cmdField->field_ptr = &cmdField->new_node; - - succeed = true; - break; - } - - case GF_SG_VRML_MFNODE: { - break; - } - - // field is not a node field - default: { - - wxString s = txtField.GetValue(); - if (s.IsEmpty()) break; - - GF_FieldInfo dummy; - dummy.far_ptr = gf_sg_vrml_field_pointer_new(field.fieldType); - dummy.fieldType = field.fieldType; - parent->GetFieldView()->SetFieldValue(dummy, &s, 0); // TODO : check the zero - - cmdField->field_ptr = dummy.far_ptr; - - succeed = true; - - break; - } - - } - - break; - } - - case GF_SG_NODE_INSERT: { - break; - } - - case GF_SG_NODE_DELETE: { - break; - } - } - - if (!succeed) { - gf_sg_command_del(c); - return; - } - - - V4SceneManager * sm = parent->GetV4SceneManager(); - - // The command is created, now searching for an AU to put it in - GF_StreamContext * ctx = sm->GetBifsStream(); - u32 count = gf_list_count (ctx->AUs); - GF_AUContext * au = NULL; - - for (u32 i = 0; i < count; i++) { - au = (GF_AUContext *) gf_list_get(ctx->AUs, i); - // V4Studio only uses timing - // TODO : FPS is defined in V4SceneGraph.h, should change and become a property somewhere - // TODO : units is a constant - if ( au->timing == sm->GetUnits() / sm->GetFrameRate() * frame ) break; - au = NULL; - } - - // creates new AU at the right time if none found - if (!au) au = gf_sm_stream_au_new(ctx, sm->GetUnits() / sm->GetFrameRate() * frame, 0, false); - - // adds command to AU and to the cell - gf_list_add(au->commands, (void *) c); - parent->GetTimeLine()->AddCommand(c); - - //gf_sg_command_apply(parent->GetV4Scene()->GetSceneGraph(), c, 0); - - -/* - // checks whether there is already a command for this object - GF_List * chain = parent->timeLine->GetCommands(); - - // if we can fuse the two commands together, we do it - if (gf_list_count(chain) > 0) { - GF_Command * old; - old = (GF_Command *) gf_list_get(chain, gf_list_count(chain) - 1); - if ( (old->tag = - } -*/ - - -} - - -/************************/ -/* Refresh */ -/************************/ - -// refresh -- refresh the node and the command combo boxes -void V4CommandPanel::Refresh(u32 frame_) { - - frame = frame_; - - // update the GUI - // cmbCommands updates in turns cmbNodes and/or cmbFields - RefreshCommands(); - - // update the list of the existing command for the cell currently selected - RefreshListCommands(); -} - - -// RefreshListCommands -- -void V4CommandPanel::RefreshListCommands() { - // retrieves pointer to the node - GF_Node * node = GetCurrentNode(); - if (!node) return; - - cmbListCommands.Clear(); - - GF_Command * c; - int i=0; - - while ( c = parent->GetTimeLine()->GetCommand(i) ) { - cmbListCommands.Append(wxString(cmdNames[c->tag]), (void *) i); - i++; - } -} - - -// RefreshCommands -- lists the available commands for the selected node -void V4CommandPanel::RefreshCommands() { - - // retrieves pointer to the node - GF_Node * node = GetCurrentNode(); - if (!node) return; - - u32 oldSel = cmbCommands.GetSelection(); - - // deletes all items from the combo box - cmbCommands.Clear(); - - // Prints the different possible commands, associates them with their id - for (int i=0; iGetV4SceneManager()->pools.pool(gf_node_get_tag(node)); - - // fills the combo box - PopulateNodes(pool, node); - - break; - } - - case GF_SG_FIELD_REPLACE: { - // checks if the field combo box has a valid selection - u32 index = cmbFields.GetSelection(); - if ( index == wxNOT_FOUND ) break; - - // get the field selected - GF_FieldInfo field; - gf_node_get_field(node, index, &field); - - // if field is not a node field then exits - if ( (field.fieldType != GF_SG_VRML_SFNODE) && (field.fieldType != GF_SG_VRML_MFNODE) ) break; - - // get the pool corresponding to that field - V4NodePool &pool = parent->GetV4SceneManager()->pools.poolFromFieldName(field.name); - - // fills the combo box - PopulateNodes(pool, node); - - break; - } - - case GF_SG_NODE_INSERT: { - // we add a child, that is to say we can add any generic node, we use "shape" to find that pool - V4NodePool &pool = parent->GetV4SceneManager()->pools.pool(TAG_MPEG4_Shape); - - // fills the combo box - PopulateNodes(pool, node); - - break; - } - - default: { - return; - } - } - -} - - -// RefreshFields -- lists the fields this nodes has -void V4CommandPanel::RefreshFields() { - - // retrieves pointer to the node - GF_Node * node = GetCurrentNode(); - if (!node) return; - - // clears the combo box - cmbFields.Clear(); - - int count = gf_node_get_field_count(node); - GF_FieldInfo field; - - for (u32 i = 0; i < count; i++) { - gf_node_get_field(node, i, &field); - cmbFields.Append(field.name, (void *) i); - } - - // TODO : are there some nodes with no fields ? - cmbFields.SetSelection(0); - - OnFieldCombo(wxCommandEvent()); - -} - - -// ShowNodeSizer -- shows or hides controls in the szSelectNode sizer -void V4CommandPanel::ShowNodeSizer(bool show) { - cmbNodes.Show(show); - lblNodes.Show(show); - - // always detaches to avoid accumulation of objects - sizerM->Detach(szSelectNode); - - if (show) { - sizerM->Add(szSelectNode, 1, wxEXPAND); - RefreshNodes(); - } - - tabAdd.Layout(); -} - - - -// ShowFieldSizer -- shows or hides controls in the szSelectField sizer -void V4CommandPanel::ShowFieldSizer(bool show) { - cmbFields.Show(show); - lblFields.Show(show); - txtField.Show(false); // always hide, RefreshField may bring it back - - // always detaches to avoid accumulation of objects - sizerM->Detach(szSelectField); - sizerM->Detach(szTxtField); - - if (show) { - // here order matters, RefreshFields may add szSelectNode, so we have to had ourselves before that - sizerM->Add(szSelectField, 1, wxEXPAND); - RefreshFields(); - } - - tabAdd.Layout(); -} - - -/************************/ -/* Utils */ -/************************/ - -// IsCommandValidForNode -- tells if we can apply this command to that node -bool V4CommandPanel::IsCommandValidForNode(u32 command, GF_Node * node) { - switch (command) { - case GF_SG_FIELD_REPLACE: - case GF_SG_NODE_DELETE: - case GF_SG_NODE_REPLACE: { - return true; - break; - } - - case GF_SG_NODE_INSERT: { - // to insert a child, node must have a GF_SG_VRML_MFNODE field, other children are not "inserted" - return parent->GetV4SceneManager()->pools.NodeHasField(node, GF_SG_VRML_MFNODE); - break; - } - - } - - return false; -} - - -// GetCurrentNode -- returns the node currently selected in the timeline -GF_Node * V4CommandPanel::GetCurrentNode() { - u32 id = parent->GetTimeLine()->GetSelectedID(); - if (!id) return NULL; - - return gf_sg_find_node(parent->GetV4SceneManager()->GetSceneGraph(), id); -} - - - -// PopulateNodes -- fills the cmdNodes with nodes from pool, do not add the specified node if found -void V4CommandPanel::PopulateNodes(V4NodePool& pool, GF_Node * node) { - for (u32 i = 0; i != pool.GetNodesCount(); i++) - if (pool.at(i).GetNode() != node) - cmbNodes.Append(pool.at(i).GetName(), (void *) pool.at(i).GetNode()); -} \ No newline at end of file diff --git a/applications/v4studio/V4CommandPanel.h b/applications/v4studio/V4CommandPanel.h deleted file mode 100644 index 1f169e1..0000000 --- a/applications/v4studio/V4CommandPanel.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - V4CommandPanel.h - - Header file for CommandPanel, the control alloing to create commands from the timeline -*/ - -#ifndef _V4CommandPanel_h_ -#define _V4CommandPanel_h_ - -#include "safe_include.h" -#include -#include - -// list of all commands -#include - - -#define cmbCommandID wxID_HIGHEST+1 -#define cmbFieldID wxID_HIGHEST+2 -#define CreateID wxID_HIGHEST+3 - - -class V4StudioFrame; -class V4NodePool; - - -class V4CommandPanel : public wxPanel { - public: - // Constructor Destructor - V4CommandPanel(V4StudioFrame * parent); - ~V4CommandPanel(); - - // Update - void Refresh(u32 frame); - - private: - - u32 frame; - - // controls - - wxNotebook tabs; - wxPanel tabView; - wxPanel tabAdd; - - // add page - wxComboBox cmbCommands; - wxStaticText lblCommands; - - wxComboBox cmbNodes; - wxStaticText lblNodes; - - wxComboBox cmbFields; - wxStaticText lblFields; - - wxButton btnCreate; - - wxTextCtrl txtField; - - - // view page - wxComboBox cmbListCommands; - wxTextCtrl txtDesc; - wxButton btnDelete; - - //sizers - // global - wxBoxSizer * sizerTabs; - // Add page - wxBoxSizer * sizerAdd, * sizerU, * sizerM, * sizerD, * szSelectNode, * szSelectField, * szTxtField; - // View page - wxBoxSizer * sizerView, * sizerUp, * sizerDown; - - - // UI -- show or hides part of the control - void ShowNodeSizer(bool show); - void ShowFieldSizer(bool show); - - // Refreshing of various comboboxes - void RefreshCommands(); - void RefreshNodes(); - void RefreshFields(); - void RefreshListCommands(); - - // fills the cmdNodes with nodes from pool, do not add the specified node if found - void PopulateNodes(V4NodePool& pool, GF_Node * node); - - // events - DECLARE_EVENT_TABLE() - void OnPaint(wxPaintEvent& event); - void OnCommandCombo(wxCommandEvent &event); - void OnFieldCombo(wxCommandEvent &event); - void OnCreateCommand(wxCommandEvent &event); - - bool IsCommandValidForNode(u32 command, GF_Node * node); // tells if we can apply this command to that node - GF_Node * GetCurrentNode(); // returns the node currently selected in the timeline - - // All the component of the V4Studio Main Frame have a pointer to that Main Frame, called parent. - V4StudioFrame * parent; - -}; - -#endif \ No newline at end of file diff --git a/applications/v4studio/V4FieldList.cpp b/applications/v4studio/V4FieldList.cpp deleted file mode 100644 index f6b1e50..0000000 --- a/applications/v4studio/V4FieldList.cpp +++ /dev/null @@ -1,452 +0,0 @@ -#include "safe_include.h" - -// For compilers that supports precompilation , includes "wx/wx.h" -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include -#include - -#include "V4FieldList.h" - -#include "V4StudioFrame.h" - -BEGIN_EVENT_TABLE(V4FieldList, wxGrid) - EVT_GRID_CELL_CHANGE(V4FieldList::OnCellChanged) - EVT_GRID_CELL_LEFT_CLICK(V4FieldList::OnCellLeftClick) - EVT_GRID_CELL_RIGHT_CLICK(V4FieldList::OnCellRightClick) - EVT_GRID_CELL_LEFT_DCLICK(V4FieldList::OnCellLeftDClick) -END_EVENT_TABLE() - -class Position { -public : - Position(u32 fi, s32 fp) : fieldIndex(fi), fieldPosition(fp) {} - u32 fieldIndex; - s32 fieldPosition; -}; - -V4FieldList::V4FieldList(wxWindow *parent_, wxSize size) : wxGrid(parent_, -1, wxDefaultPosition, size) { - positions = gf_list_new(); - CreateGrid(0,0); - SetRowLabelSize(0); - SetColLabelSize(20); - SetColLabelValue(0, wxString(" ")); - SetColLabelValue(1, wxString("Field Name")); - SetColLabelValue(2, wxString("Field Value")); - InsertCols(0,3); - AutoSizeColumns(true); - EnableGridLines(true); - - parent = (V4StudioFrame *) parent_; -} - -V4FieldList::~V4FieldList() -{ - s32 i; - for (i=gf_list_count(positions)-1; i>=0; i--) { - Position *p = (Position *)gf_list_get(positions, i); - delete p; - p = NULL; - gf_list_rem(positions, i); - } - gf_list_del(positions); -} - -void V4FieldList::Create() -{ - GF_Node *node = m_pNode; - - if (!node) return; - - DeleteCols(0,3); - u32 nbRows = GetNumberRows(); - if (nbRows) DeleteRows(0,nbRows); - InsertCols(0,3); - - s32 i; - for (i=gf_list_count(positions)-1; i>=0; i--) { - Position *p = (Position *)gf_list_get(positions, i); - delete p; - p = NULL; - gf_list_rem(positions, i); - } - - u32 pos = 0; // counts rows added - - // adds a row to modify DefName - InsertRows(pos, 1); - SetCellValue(pos, 1, wxString("Name")); - const char * defName = gf_node_get_name(node); - if (defName) SetCellValue(pos, 2, wxString(defName)); - gf_list_add(positions, new Position(-1, -1)); - // enables modifying the DefName - for (i=0; i<2; i++) SetReadOnly(pos, i, TRUE); - SetReadOnly(pos, 2, FALSE); - pos++; - - // adds all fields - GF_FieldInfo field; - u32 count = gf_node_get_field_count(node); - u32 j; - - for (j=0; jc_str(), "%f %f %f", &(((SFColor *)ptr)->red), &(((SFColor *)ptr)->green), &(((SFColor *)ptr)->blue)); - break; - case GF_SG_VRML_SFVEC2F: - sscanf(value->c_str(), "%f %f", &(((SFVec2f *)ptr)->x), &(((SFVec2f *)ptr)->y)); - break; - case GF_SG_VRML_SFFLOAT: - sscanf(value->c_str(), "%f", (SFFloat *)ptr); - break; - case GF_SG_VRML_SFINT32: - sscanf(value->c_str(), "%d", (SFInt32 *)ptr); - break; - case GF_SG_VRML_SFBOOL: - if (!stricmp(value->c_str(), "true")) *((SFBool *)ptr) = 1; - else *((SFBool *)ptr) = 0; - break; - case GF_SG_VRML_SFSTRING: - if (((SFString *)ptr)->buffer) gf_free(((SFString *)ptr)->buffer); - ((SFString *)ptr)->buffer = gf_strdup(value->c_str()); - break; - default: - break; - } -} - -void V4FieldList::GetFieldValue(GF_FieldInfo f, wxString *s, int pos) -{ - void *ptr = NULL; - s32 type = -1; - if (gf_sg_vrml_is_sf_field(f.fieldType)) { - type = f.fieldType; - ptr = f.far_ptr; - } else { - if (pos < 0) return; - gf_sg_vrml_mf_get_item(f.far_ptr, f.fieldType, &ptr, pos); - type = gf_sg_vrml_get_sf_type(f.fieldType); - } - switch (type) { - case GF_SG_VRML_SFBOOL: - if (*(SFBool *)ptr == 0) s->Printf("false"); - else s->Printf("true"); - break; - case GF_SG_VRML_SFINT32: - s->Printf("%d", *(SFInt32 *)ptr); - break; - case GF_SG_VRML_SFCOLOR: - s->Printf("%.2f %.2f %.2f", ((SFColor *)ptr)->red, ((SFColor *)ptr)->green, ((SFColor *)ptr)->blue); - break; - case GF_SG_VRML_SFVEC2F: - s->Printf("%.2f %.2f", ((SFVec2f *)ptr)->x, ((SFVec2f *)ptr)->y); - break; - case GF_SG_VRML_SFFLOAT: - s->Printf("%.2f", *(SFFloat *)ptr); - break; - case GF_SG_VRML_SFSTRING: - s->Printf("%s", ((SFString *)ptr)->buffer); - break; - case GF_SG_VRML_SFSCRIPT: - s->Printf("%s", ((SFScript *)ptr)->script_text); - break; - default: - break; - } - gf_node_dirty_set(m_pNode, 0, 1); -} - -// OnCellChanged -- user has validated the changes made to a field, updates the node with the new value -void V4FieldList::OnCellChanged(wxGridEvent &evt) -{ - u32 row; - GF_FieldInfo field; - wxString value; - - if (!m_pNode || evt.GetCol() == 0) { - evt.Skip(); - return; - } - - row = evt.GetRow(); - value = GetCellValue(row, 2); - Position *pSelected = (Position *)gf_list_get(positions, row); - if (!pSelected) { - evt.Skip(); - return; - } - - // defName requires special treatment - if (pSelected->fieldIndex == (u32) -1) { - u32 id = gf_node_get_id(m_pNode); - if (!id) id = gf_sg_get_next_available_node_id(parent->GetV4SceneManager()->GetSceneGraph()); - gf_node_set_id(m_pNode, id, value.c_str()); - parent->GetV4SceneManager()->pools.Add(m_pNode); - } else { - // modifies any kind of field - gf_node_get_field(m_pNode, pSelected->fieldIndex, &field); - if (gf_sg_vrml_is_sf_field(field.fieldType)) { - SetFieldValue(field, &value, -1); - } else { - if (pSelected->fieldPosition >= 0) { - SetFieldValue(field, &value, pSelected->fieldPosition); - } else { - GenMFField *mf = (GenMFField *)field.far_ptr; - void *ptr; - gf_sg_vrml_mf_insert(mf, field.fieldType, &ptr, mf->count); - SetFieldValue(field, &value, mf->count-1); - SetCellValue(row, 2, ""); - wxString sign = GetCellValue(row, 0); - switch (sign.GetChar(0)) { - case '-': - { - u32 insertPosition = row+mf->count+1; - InsertRows(insertPosition-1, 1); - gf_list_insert(positions, new Position(pSelected->fieldIndex, mf->count-1), insertPosition); - wxString tmp; - tmp << '['; tmp << (mf->count-1); tmp << ']'; - SetCellValue(insertPosition-1, 1, tmp); - wxString buf; - GetFieldValue(field, &buf, mf->count-1); - SetCellValue(insertPosition-1, 2, buf); - } - break; - case '+': - break; - case ' ': - SetCellValue(row, 0, "+"); - break; - } - } - } - } - gf_node_dirty_set(m_pNode, 0, 1); - V4StudioFrame *parent = (V4StudioFrame *)this->GetParent(); - parent->Update(); -} - -void V4FieldList::SetLog(wxString s) -{ - V4StudioFrame *parent = (V4StudioFrame *)this->GetParent(); - parent->GetStatusBar()->SetStatusText(s); -} - -void V4FieldList::SetCellFieldValue(GF_FieldInfo field, u32 pos) -{ - wxString buf; - if (gf_sg_vrml_is_sf_field(field.fieldType)) { - SetCellValue(pos,1,wxString(field.name)); - GetFieldValue(field, &buf, -1); - SetCellValue(pos,2,buf); - } else { - GenMFField *mf = (GenMFField *)field.far_ptr; - if (mf->count > 0 ) { - SetCellValue(pos,0,"+"); - } else { - SetCellValue(pos,0," "); - } - SetCellValue(pos,1,field.name); - } -} - -// OnCellLeftClick -- draws columns for multivalued fields -void V4FieldList::OnCellLeftClick(wxGridEvent &evt) -{ - u32 col = evt.GetCol(); - u32 row = evt.GetRow(); - GF_FieldInfo field; - GF_Node *node = m_pNode; - - if (col != 0) { - evt.Skip(); - return; - } - - Position *pSelected = (Position *)gf_list_get(positions, row); - if (!pSelected) { - evt.Skip(); - return; - } - - gf_node_get_field(node, pSelected->fieldIndex, &field); - if (gf_sg_vrml_is_sf_field(field.fieldType) || field.fieldType == GF_SG_VRML_MFNODE) { - evt.Skip(); - return; - } - - wxString value = GetCellValue(row, col); - char c = value.GetChar(0); - GenMFField *mf = (GenMFField *)field.far_ptr; - if (c == ' ') { - evt.Skip(); - return; - } else if (c == '+') { - value.SetChar(0, '-'); - SetCellValue(row,0,value); - InsertRows(row+1, mf->count); - for (u32 j = 0; jcount; j++) { - Position *p = new Position(pSelected->fieldIndex, j); - gf_list_insert(positions, p, row+1+j); - wxString tmp; - tmp << '['; tmp << j; tmp << ']'; - SetCellValue(row+1+j, 1, tmp); - wxString buf; - GetFieldValue(field, &buf, j); - SetCellValue(row+1+j, 2, buf); - } - } else if (c == '-') { - value.SetChar(0, '+'); - SetCellValue(row,0,value); - DeleteRows(row+1, mf->count); - for (s32 j = mf->count-1; j>=0; j--) { - Position *p = (Position *)gf_list_get(positions,row+1+j); - delete p; - p = NULL; - gf_list_rem(positions, row+1+j); - } - } - evt.Skip(); -} - -void V4FieldList::OnCellRightClick(wxGridEvent &evt) -{ - int row = evt.GetRow(); - GF_FieldInfo field; - GF_Node *node = m_pNode; - - Position *pSelected = (Position *)gf_list_get(positions,row); - if (!pSelected) { - evt.Skip(); - return; - } - - gf_node_get_field(node, pSelected->fieldIndex, &field); - if (gf_sg_vrml_is_sf_field(field.fieldType)) { - evt.Skip(); - return; - } - - GenMFField *mf = (GenMFField *)field.far_ptr; - if (pSelected->fieldPosition == -1) { - evt.Skip(); - return; - } - - InsertRows(row, 1); - gf_list_insert(positions, new Position(pSelected->fieldIndex, pSelected->fieldPosition), row); - void *ptr; - gf_sg_vrml_mf_insert(mf, field.fieldType, &ptr, pSelected->fieldPosition); - SetCellValue(row, 2, ""); - for (u32 i=pSelected->fieldPosition; icount; i++) { - wxString tmp; - tmp << '['; tmp << i; tmp << ']'; - SetCellValue(row+i, 1, tmp); - } -} - -// OnCellLeftDClick -- Edit a given field -void V4FieldList::OnCellLeftDClick(wxGridEvent &evt) -{ - int row = evt.GetRow(); - GF_FieldInfo field; - GF_Node *node = m_pNode; - - Position *pSelected = (Position *)gf_list_get(positions,row); - if (!pSelected) { - evt.Skip(); - return; - } - - // editing the DEF name is NOT modifying a field - // we just need to modify the string itself - if (pSelected->fieldIndex == (u32) -1) { - evt.Skip(); - return; - } - - gf_node_get_field(node, pSelected->fieldIndex, &field); - u32 type; - void *ptr; - if (gf_sg_vrml_is_sf_field(field.fieldType)) { - type = field.fieldType; - ptr = field.far_ptr; - } else { - if (pSelected->fieldPosition < 0) { - evt.Skip(); - return; - } - gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &ptr, pSelected->fieldPosition); - type = gf_sg_vrml_get_sf_type(field.fieldType); - } - - if (type== GF_SG_VRML_SFCOLOR) { - wxColourDialog cd(this); - if (cd.ShowModal() == wxID_OK) - { - wxColourData retData = cd.GetColourData(); - wxColour col = retData.GetColour(); - ((SFColor *)ptr)->red = col.Red()/255.0f; - ((SFColor *)ptr)->green = col.Green()/255.0f; - ((SFColor *)ptr)->blue = col.Blue()/255.0f; - } else { - return; - } - } else if (!stricmp(field.name,"family")) { - wxFontDialog fd(this); - if (fd.ShowModal() == wxID_OK) { - wxFontData retData = fd.GetFontData(); - wxFont font = retData.GetChosenFont(); - wxString name = font.GetFaceName(); - if (((SFString *)ptr)->buffer) gf_free(((SFString *)ptr)->buffer); - ((SFString *)ptr)->buffer = gf_strdup(name.c_str()); - } else { - return; - } - - } else { - evt.Skip(); - return; - } - V4StudioFrame *parent = (V4StudioFrame *)this->GetParent(); - parent->Update(); -} diff --git a/applications/v4studio/V4FieldList.h b/applications/v4studio/V4FieldList.h deleted file mode 100644 index d4142c5..0000000 --- a/applications/v4studio/V4FieldList.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _V4_FIELD_LIST_H -#define _V4_FIELD_LIST_H - -#include "safe_include.h" -#include - -#include - - -class V4StudioFrame; - - -class V4FieldList: public wxGrid { - -public: - V4FieldList(wxWindow *parent, wxSize size); - ~V4FieldList(); - - void SetNode(GF_Node *node) { m_pNode = node; } - - void Create(); - void GetFieldValue(GF_FieldInfo f, wxString *s, int pos); - void SetFieldValue(GF_FieldInfo f, wxString *s, int pos); - - void OnCellChanged(wxGridEvent &evt); - void OnCellLeftClick(wxGridEvent &evt); - void OnCellRightClick(wxGridEvent &evt); - void OnCellLeftDClick(wxGridEvent &evt); -protected: - DECLARE_EVENT_TABLE() - -private: - void SetLog(wxString s); - - void InsertOneFieldRow(u32 position, GF_FieldInfo field); - - void SetCellFieldValue(GF_FieldInfo field, u32 pos); - - GF_Node * m_pNode; - GF_List *positions; - - // All the component of the V4Studio Main Frame have a pointer to that Main Frame, called parent. - V4StudioFrame * parent; - -}; - -#endif diff --git a/applications/v4studio/V4Node.cpp b/applications/v4studio/V4Node.cpp deleted file mode 100644 index 75ca8f9..0000000 --- a/applications/v4studio/V4Node.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - V4Node.cpp - - Implements V4Node class -*/ - -#include "V4Node.h" -#include - - -// Constructor -V4Node::V4Node(const u32 _NodeID, GF_Node * _node) : NodeID(_NodeID), node(_node) { - _ASSERT(_node); // no NULL node -} - - -// GetID -- -u32 V4Node::GetID() const { - return NodeID; -} - - -// GetNode -- -GF_Node * V4Node::GetNode() const { - return node; -} - - -// IsAliveAt -- check all aparitions -bool V4Node::IsAliveAt(const u32 frame) { - std::list::iterator i; - - for (i = lifeSpan.begin(); i != lifeSpan.end(); i++) - if ( ((*i).from >= frame) && ((*i).to <= frame) ) return true; - - return false; -} - - -// Appear -void V4Node::Appear(const u32 startFrame, const u32 stopFrame) { - // TODO : - return; -} - - -// Disappear -void V4Node::Disappear(const u32 startFrame, const u32 stopFrame) { - // TODO : - return; -} - - -// GetName -- -wxString V4Node::GetName() { - return wxString(gf_node_get_name(node)); -} \ No newline at end of file diff --git a/applications/v4studio/V4Node.h b/applications/v4studio/V4Node.h deleted file mode 100644 index 815bbf2..0000000 --- a/applications/v4studio/V4Node.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - V4Node.h - - Represents a node with additionnal attributes for V4Studio, such as lifespan -*/ - -#ifndef _V4Node_ -#define _V4Node_ - -#include "safe_include.h" -#include // GF_Node structure - -#include - -#include - - -struct segment { - u32 from, to; -}; - - -class V4Node { - public: - // constructor destructor - V4Node(const u32 NodeID, GF_Node * node=NULL); // node may be modified, don't use const GF_Node * - - // accesses to members - u32 GetID() const; - GF_Node * GetNode() const; - - - // computes whether the node is alive at the given frame - bool IsAliveAt(const u32 frame); - - // Add an apparition, inclusive - void Appear(const u32 startFrame, const u32 stopFrame); - - // Remove frames from lifeSpan, inclusive - void Disappear(const u32 startFrame, const u32 stopFrame); - - - // (to save workspace) tells whether the node should appear on the timeline - bool isOnTimeLine; - - // retrieves the node _DEF_ name (node has a Node ID) - wxString GetName(); - - - - private: - // various accesses to the node - u32 NodeID; - GF_Node * node; - - // timeLine - std::list lifeSpan; // each element of the list is one use of this node, first value is start frame, second is end frame, inclusive - -}; - -#endif \ No newline at end of file diff --git a/applications/v4studio/V4NodePool.cpp b/applications/v4studio/V4NodePool.cpp deleted file mode 100644 index f78f6fc..0000000 --- a/applications/v4studio/V4NodePool.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - V4NodePool.cpp - -*/ -#include "safe_include.h" -#include - -#include "V4NodePool.h" - - -// FindNode -- search for a node with the specified NodeID or pointer -u32 V4NodePool::FindNode(const u32 NodeID, const GF_Node * node) { - - if ( (NodeID == 0) && (node == NULL) ) return (u32) -1; - - for (int i = 0; i < Nodes.size(); i++) - if ( (NodeID == Nodes.at(i).GetID()) || (node == Nodes.at(i).GetNode()) ) return i; - - return (u32) -1; -} - - -// AddNode -- -V4Node& V4NodePool::AddNode(GF_Node * _node) { - // checks that the node is not already in the pool - u32 id = gf_node_get_id(_node); - u32 i = FindNode(id); - if (i != (u32) -1) return Nodes.at(i); - - // add a new entry into the pool - V4Node node(id, _node); - Nodes.push_back(node); - count++; - return Nodes.back(); -} - - -// DeleteNode -- Deletes a node from the pool -void V4NodePool::DeleteNode(const u32 _NodeID, const GF_Node * _node) { - u32 i = FindNode(_NodeID, _node); - std::vector::iterator iter = Nodes.begin(); - - for (u32 j=0; j -#include "V4Node.h" - -using namespace std; - -class V4NodePool { - - public: - - // Constructor - V4NodePool() { count = 0; } - - // Adds a node to the pool - V4Node& AddNode(GF_Node * node=NULL); // node may be modified, don't use const GF_Node * - - // Deletes a node from the pool - void DeleteNode(const u32 NodeID, const GF_Node * node=NULL); - - // retrieves a node from the pool - V4Node& GetV4Node(const u32 NodeID, const GF_Node * node=NULL); - - // returns the numbre of nodes - u32 GetNodesCount() const; - - // returns the nth element in the vector - V4Node& at(u32 n); - - // clear the pool - void Clear(); - - // returns count - u32 GetCount() const; - - - private: - vector Nodes; - - // find the V4Node with the specified attributes - u32 FindNode(const u32 NodeID, const GF_Node * node=NULL); - - // counts the nodes added to that pool (used in autonaming nodes) - u32 count; - -}; - -#endif \ No newline at end of file diff --git a/applications/v4studio/V4NodePools.cpp b/applications/v4studio/V4NodePools.cpp deleted file mode 100644 index 2168dba..0000000 --- a/applications/v4studio/V4NodePools.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - V4NodePools.cpp - - Implements V4NodePools class - -*/ - -#include "V4NodePools.h" -#include "V4NodePool.h" - -V4NodePool dummy; - -// Constructor -V4NodePools::V4NodePools() { - pools.resize(DICT_LAST); - unPooled = 0; -} - - -// pool -- returns the pool of object for the given tag -V4NodePool& V4NodePools::pool(const u32 tag) -{ - u32 n = poolN(tag); - if ((u32) -1 == n) return dummy; - return pools.at(n); -} - - -// pool -- returns the NUMBER of the pool for the given tag -u32 V4NodePools::poolN(const u32 tag) { - - switch (tag) { - - // objects that can be children of a switch - case TAG_MPEG4_OrderedGroup: - case TAG_MPEG4_Shape: { - return DICT_GEN; - break; - } - - // objects that can be a geometry - case TAG_MPEG4_Rectangle: - case TAG_MPEG4_IndexedFaceSet2D: - case TAG_MPEG4_Circle: { - return DICT_GEOMETRY; - break; - } - - // objects that can be an appearance - case TAG_MPEG4_Appearance: { - return DICT_APPEARANCE; - break; - } - - // objects that can be a texture - case TAG_MPEG4_MovieTexture: - case TAG_MPEG4_ImageTexture: { - return DICT_TEXTURE; - break; - } - - // objects that can be a material - case TAG_MPEG4_Material2D: { - return DICT_MATERIAL; - break; - } - - } - - return (u32) -1; -} - - -// poolNFromFieldName -- Get the correct pool from a field name -V4NodePool& V4NodePools::poolFromFieldName(const char * name) { - - if (!strcmp("appearance", name)) return pools.at(DICT_APPEARANCE); - if (!strcmp("geometry", name)) return pools.at(DICT_GEOMETRY); - if (!strcmp("material", name)) return pools.at(DICT_MATERIAL); - if (!strcmp("texture", name)) return pools.at(DICT_TEXTURE); - - // throws an exception if not found - return dummy; -} - - -// Clear -- clears all the pool -void V4NodePools::Clear() { - for (u32 i = 0; i < pools.size(); i++) - pools.at(i).Clear(); -} - - -// Add -- Adds a node to the correct pool -void V4NodePools::Add(GF_Node * node) { - u32 tag = gf_node_get_tag(node); - if (poolN(tag) == (u32) -1) return; - pool(tag).AddNode(node); -} - - -// NodeHasField -- tells if nodes as field of the given type -bool V4NodePools::NodeHasField(GF_Node * node, u32 fieldType) { - u32 count = gf_node_get_field_count(node); - GF_FieldInfo field; - - // cycles through all fields and checks field type - for (u32 i = 0; i < count; i++) { - gf_node_get_field(node, i, &field); - if (field.fieldType == fieldType) return true; - } - - return false; -} - - -// returns the total number of nodes created for that type of node -u32 V4NodePools::GetCount(const u32 tag) { - if (poolN(tag) == (u32) -1) return unPooled++; - return pool(tag).GetCount(); -} \ No newline at end of file diff --git a/applications/v4studio/V4NodePools.h b/applications/v4studio/V4NodePools.h deleted file mode 100644 index a9f0107..0000000 --- a/applications/v4studio/V4NodePools.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - V4NodePools - - List all the Node pools for each possible node tag - -*/ - -#include "safe_include.h" -#include -#include - -#include - -#include "V4NodePool.h" - - -using namespace std; - - -enum { - DICT_GEN = 0, - DICT_GEOMETRY, - DICT_APPEARANCE, - DICT_TEXTURE, - DICT_MATERIAL, - - DICT_LAST // last element, gives the actual number of pool -}; - - -class V4NodePools { - - public: - // Constructor - V4NodePools(); - - // gets the correct pool from the given tag - V4NodePool& pool(const u32 tag); - V4NodePool& poolFromFieldName(const char * name); - u32 poolN(const u32 tag); - - // clears all the pools - void Clear(); - - // Adds a node to the correct pool - void Add(GF_Node * node); - - // tells if nodes as field of the given type - bool NodeHasField(GF_Node * node, u32 fieldType); - - // returns the total number of nodes created for that type of node - u32 GetCount(const u32 tag); - - - private: - vector pools; - unsigned int unPooled; - -}; \ No newline at end of file diff --git a/applications/v4studio/V4SceneGraph.cpp b/applications/v4studio/V4SceneGraph.cpp deleted file mode 100644 index 05558ac..0000000 --- a/applications/v4studio/V4SceneGraph.cpp +++ /dev/null @@ -1,304 +0,0 @@ -#include "V4SceneGraph.h" -#include "V4StudioFrame.h" - -#include -#include -#include - -#include "V4Service.h" - -V4SceneGraph::V4SceneGraph(V4StudioFrame *parent) : frame(parent) -{ - m_pSm = NULL; - m_pSg = NULL; - m_pSr = NULL; - m_pIs = NULL; - m_pOriginal_mp4 = NULL; - m_bEncodeNames = 0; - m_term = parent->GetGPACPanel()->m_term; -} - -V4SceneGraph::~V4SceneGraph() -{ - // TODO : pquoi fallait il commenter cette ligne ? - //if (m_pSm) gf_sm_del(m_pSm); - if (m_pOriginal_mp4) gf_free(m_pOriginal_mp4); - if (m_pService) delete m_pService; -} - -void V4SceneGraph::SetSceneSize(int w, int h) -{ - gf_sg_set_scene_size_info(m_pSg, w,h, 1); - /*reassign scene graph to update scene size in renderer*/ - gf_sr_set_scene(m_pSr, m_pSg); -} - -void V4SceneGraph::GetSceneSize(wxSize &size) -{ - gf_sg_get_scene_size_info(m_pSg, (u32 *)&(size.x), (u32 *)&(size.y)); -} - -GF_Node *V4SceneGraph::SetTopNode(u32 tag) -{ - GF_Node * root = NewNode(tag); - gf_sg_set_root_node(m_pSg, root); - return (GF_Node *)root; -} - - -GF_Node *V4SceneGraph::NewNode(u32 tag) -{ - GF_Node *n = gf_node_new(m_pSg, tag); - if (!n) return NULL; - gf_node_init(n); - return n; -} - -void V4SceneGraph::SaveFile(const char *path) -{ - char rad_name[5000]; - strcpy(rad_name, "dump"); - gf_sm_dump(m_pSm, rad_name, 0); - GF_ISOFile *mp4 = gf_isom_open(path, GF_ISOM_WRITE_EDIT, NULL); - m_pSm->max_node_id = gf_sg_get_max_node_id(m_pSm->scene_graph); - gf_sm_encode_to_file(m_pSm, mp4, "c:\\log.txt", NULL, GF_SM_LOAD_MPEG4_STRICT, 0); - gf_isom_close(mp4); -} - -void V4SceneGraph::LoadNew() -{ - if (m_pSm) { - gf_sr_set_scene(m_pSr, NULL); - gf_sm_del(m_pSm); - m_pSm = NULL; - gf_sg_del(m_pSg); - m_pSg = NULL; - } - if (m_pOriginal_mp4) gf_free(m_pOriginal_mp4); - m_pOriginal_mp4 = NULL; - - m_pIs = gf_is_new(NULL); - m_pSg = m_pIs->graph; - gf_sg_set_init_callback(m_pSg, v4s_node_init, this); - gf_sr_set_scene(m_pSr, m_pSg); - - m_pSm = gf_sm_new(m_pSg); - /* Create a BIFS stream with one AU with on ReplaceScene */ - GF_StreamContext *sc = gf_sm_stream_new(m_pSm, 1, GF_STREAM_SCENE, 0); - GF_AUContext *au = gf_sm_stream_au_new(sc, 0, 0, 1); - GF_Command *command = gf_sg_command_new(m_pSg, GF_SG_SCENE_REPLACE); - gf_list_add(au->commands, command); - - // reinitializes the node pool - frame->pools.Clear(); -} - -void V4SceneGraph::LoadFileOld(const char *path) -{ - m_pService = new V4Service(path); - gf_term_attach_service(m_term, m_pService->m_pNetClient); - m_pIs = m_term->root_scene; - m_pSg = m_pIs->graph; - gf_term_play_from_time(m_term, 0); - while(!m_pIs->graph_attached) {} - // CreateDictionnary crashes because the root node in m_pSg is not set. - CreateDictionnary(); -} - -void V4SceneGraph::LoadFile(const char *path) -{ - GF_SceneLoader load; - if (m_pSm) { - gf_sr_set_scene(m_pSr, NULL); - gf_sm_del(m_pSm); - gf_sg_del(m_pSg); - } - - // initializes a new scene - // We need an GF_InlineScene, a SceneManager and an GF_ObjectManager - m_pIs = gf_is_new(NULL); - m_pSg = m_pIs->graph; - m_pSm = gf_sm_new(m_pSg); - - m_pIs->root_od = gf_odm_new(); - - m_pIs->root_od->parentscene = NULL; - m_pIs->root_od->subscene = m_pIs; - m_pIs->root_od->term = m_term; - - m_term->root_scene = m_pIs; - - // TODO : what's the use of this ? - if (m_pOriginal_mp4) gf_free(m_pOriginal_mp4); - m_pOriginal_mp4 = NULL; - - /* Loading of a file (BT, MP4 ...) and modification of the SceneManager */ - memset(&load, 0, sizeof(GF_SceneLoader)); - load.fileName = path; - load.ctx = m_pSm; - load.cbk = this; - if (strstr(path, ".mp4") || strstr(path, ".MP4") ) load.isom = gf_isom_open(path, GF_ISOM_OPEN_READ, NULL); - gf_sm_load_init(&load); - gf_sm_load_run(&load); - gf_sm_load_done(&load); - if (load.isom) gf_isom_delete(load.isom); - - /* SceneManager should be initialized and filled correctly */ - - gf_sg_set_scene_size_info(m_pSg, m_pSm->scene_width, m_pSm->scene_height, m_pSm->is_pixel_metrics); - - // TODO : replace with GetBifsStream - GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0); - - if (sc->streamType == 3) { - GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0); - GF_Command *c = (GF_Command *) gf_list_get(au->commands,0); - gf_sg_command_apply(m_pSg, c, 0); - /* This is a patch to solve the save pb: - When ApplyCommand is made on a Scene Replace Command - The command node is set to NULL - When we save a BIFS stream whose first command is of this kind, - the file saver thinks the bifs commands should come from an NHNT file - This is a temporary patch */ - if (c->tag == GF_SG_SCENE_REPLACE) { c->node = m_pSg->RootNode; } - } - gf_sr_set_scene(m_pSr, m_pSg); - - // retrieves all the node from the tree and adds them to the node pool - GF_Node * root = gf_sg_get_root_node(m_pSg); - CreateDictionnary(); -} - -GF_Node *V4SceneGraph::CopyNode(GF_Node *node, GF_Node *parent, bool copy) -{ - if (copy) return CloneNodeForEditing(m_pSg, node); - u32 nodeID = gf_node_get_id(node); - if (!nodeID) { - nodeID = gf_sg_get_next_available_node_id(m_pSg); - gf_node_set_id(node, nodeID, NULL); - gf_node_register(node, parent); - } - return node; -} - -void V4SceneGraph::LoadCommand(u32 commandNumber) -{ - GF_StreamContext *sc = NULL; - for (u32 i=0; istreams); i++) { - sc = (GF_StreamContext *) gf_list_get(m_pSm->streams, i); - if (sc->streamType == GF_STREAM_SCENE) break; - sc = NULL; - } - assert(sc); - GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0); - if (commandNumber < gf_list_count(au->commands)) { - for (u32 j=0; j<=commandNumber; j++) { - GF_Command *c = (GF_Command *) gf_list_get(au->commands, j); - gf_sg_command_apply(m_pSg, c, 0); - } - } -} - - - -extern "C" { - -GF_Node *CloneNodeForEditing(GF_SceneGraph *inScene, GF_Node *orig) //, GF_Node *cloned_parent) -{ - u32 i, j, count; - GF_Node *node, *child, *tmp; - GF_List *list, *list2; - GF_FieldInfo field_orig, field; - - /*this is not a mistake*/ - if (!orig) return NULL; - - /*check for DEF/USE - if (orig->sgprivate->NodeID) { - node = gf_sg_find_node(inScene, orig->sgprivate->NodeID); - //node already created, USE - if (node) { - gf_node_register(node, cloned_parent); - return node; - } - } - */ - /*create a node*/ -/* - if (orig->sgprivate->tag == TAG_MPEG4_ProtoNode) { - proto_node = ((GF_ProtoInstance *)orig)->proto_interface; - //create the instance but don't load the code -c we MUST wait for ISed routes to be cloned before - node = gf_sg_proto_create_node(inScene, proto_node, (GF_ProtoInstance *) orig); - } else { -*/ - node = gf_node_new(inScene, gf_node_get_tag(orig)); -// } - - count = gf_node_get_field_count(orig); - - /*copy each field*/ - for (i=0; isgprivate->NodeID) { - Node_SetID(node, orig->sgprivate->NodeID); - gf_node_register(node, cloned_parent); - }*/ - - /*init node before creating ISed routes so the eventIn handler are in place*/ - if (gf_node_get_tag(node) != TAG_ProtoNode) gf_node_init(node); - - return node; -} - -} - - -// GetBifsStream -- gets the first stream with id = 3 -GF_StreamContext * V4SceneGraph::GetBifsStream() { - GF_StreamContext * ctx = NULL; - u32 count = gf_list_count(m_pSm->streams); - - // cycle trough each stream - while (count--) { - ctx = (GF_StreamContext *) gf_list_get(m_pSm->streams, count); - if (ctx->streamType == 3) break; - } - - if (ctx == NULL) return NULL; - - // if we went through the loop without finding any BIFS stream return null - if (ctx->streamType != 3) return NULL; - - return ctx; -} - - diff --git a/applications/v4studio/V4SceneGraph.h b/applications/v4studio/V4SceneGraph.h deleted file mode 100644 index cc6dc07..0000000 --- a/applications/v4studio/V4SceneGraph.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef _V4SCENEGRAPH_H -#define _V4SCENEGRAPH_H - -#include "safe_include.h" -#include -#include -#include // MPEG4CLIENT - - -#include - - -#define DICTNAME "__V4dictionnary" - - -#define FPS 25 - - -class V4StudioFrame; -class V4Service; - -extern "C" { - GF_Node *CloneNodeForEditing(GF_SceneGraph *inScene, GF_Node *orig); - int GetNextNodeID(GF_SceneGraph *sg); -} - -class V4SceneGraph { -public: - // Constructor / Desctructor - V4SceneGraph(V4StudioFrame *parent); - ~V4SceneGraph(); - - - /* file management functions */ - - void SaveFile(const char * path); - void LoadNew(); - void LoadFile(const char *path); - void LoadFileOld(const char *path); - - - /* Node management functions */ - - GF_Node *NewNode(u32 tag); - GF_Node *CopyNode(GF_Node *node, GF_Node *parent, bool copy); - GF_Node *SetTopNode(u32 tag); // TODO : will destroy dictionnary - - /* Various */ - - void LoadCommand(u32 commandNumber); // ? - GF_StreamContext * GetBifsStream(); // Get the first stream with id = 3 - - - /* access to private members */ - - // SceneSize - void SetSceneSize(int w, int h); - void GetSceneSize(wxSize &size); - - // Renderer (owned by the terminal) - void SetRenderer(GF_Compositor *sr) { m_pSr = sr; } - GF_Compositor *GetSceneCompositor() { return m_pSr; } - - // GF_InlineScene - // TODO : Should be modified ? - LPINLINESCENE GetInlineScene() { return m_pIs; } - - // SceneManager - // TODO : Should be modified ? - GF_SceneManager * GetSceneManager() { return m_pSm; } - - // SceneGraph - GF_SceneGraph *GetSceneGraph() { return m_pSg; } - GF_Node *GetRootNode() { return gf_sg_get_root_node(m_pSg); } - -protected: - - // self created - LPINLINESCENE m_pIs; - GF_SceneGraph * m_pSg; - GF_SceneManager *m_pSm; - GF_Node * dictionnary; - - // from other objects - GF_Compositor *m_pSr; - GF_Terminal *m_term; - V4StudioFrame * frame; - - char *m_pOriginal_mp4; - Bool m_bEncodeNames; - V4Service *m_pService; -}; - -#endif - diff --git a/applications/v4studio/V4SceneManager.cpp b/applications/v4studio/V4SceneManager.cpp deleted file mode 100644 index ea31f89..0000000 --- a/applications/v4studio/V4SceneManager.cpp +++ /dev/null @@ -1,598 +0,0 @@ -#include "V4SceneManager.h" -#include "V4StudioFrame.h" - -#include -#include -#include -#include - - -V4SceneManager::V4SceneManager(V4StudioFrame *parent) : frame(parent) -{ - m_pSm = NULL; - m_pIs = NULL; - units = 1000; // used to calculate AU timings -} - -V4SceneManager::~V4SceneManager() -{ - GF_SceneGraph *tmp = m_pIs->graph; - - /* Deletion of the SceneManager - This is done before deleting the GF_InlineScene in the GF_Terminal in the GPAC Panel - but for that we need to register the root node one more time to avoid the deletion of the scene graph - But this is temporary, this register of the root node should be done at loading time. - */ - if (m_pSm) { - gf_node_register(m_pSm->scene_graph->RootNode, NULL); - gf_sm_del(m_pSm); - m_pSm = NULL; - } - - /* Destruction of the GPAC panel and of the associated service and terminal */ - delete m_gpac_panel; - m_gpac_panel = NULL; - -} - -void V4SceneManager::LoadCommon() -{ - /* Creation and initialization of the structure InlineScene, including the SceneGraph */ - m_pIs = gf_inline_new(NULL); - - /* Creation of the GPAC Panel which includes the creation of the terminal */ - m_gpac_panel = new wxGPACPanel(this, NULL); - - /* Connection of the InlineScene to the terminal */ - GF_Terminal *term = m_gpac_panel->GetMPEG4Terminal(); - term->root_scene = m_pIs; - -/* - gf_sc_set_scene(term->compositor, m_pIs->graph); - m_pIs->graph_attached = 1; -*/ - - /* Creation of a SceneManager to manipulate the scene and streams */ - m_pSm = gf_sm_new(m_pIs->graph); - - /* Creation of main ObjectManager to manipulate the media */ - m_pIs->root_od = gf_odm_new(); - m_pIs->root_od->parentscene = NULL; - m_pIs->root_od->subscene = m_pIs; - m_pIs->root_od->term = term; -} - -void V4SceneManager::LoadNew() -{ - LoadCommon(); - - /* Create a BIFS stream with one AU with one ReplaceScene */ - GF_StreamContext *sc = gf_sm_stream_new(m_pSm, 1, GF_STREAM_SCENE, 0); - GF_AUContext *au = gf_sm_stream_au_new(sc, 0, 0, 1); - GF_Command *command = gf_sg_command_new(m_pIs->graph, GF_SG_SCENE_REPLACE); - gf_list_add(au->commands, command); - - SetLength(50); - SetFrameRate(25); - - // reinitializes the node pool - pools.Clear(); -} - -void V4SceneManager::LoadFile(const char *path) -{ - LoadCommon(); - GF_Terminal *term = m_gpac_panel->GetMPEG4Terminal(); - - /* Loading of a file (BT, MP4 ...) and modification of the SceneManager */ - GF_SceneLoader load; - memset(&load, 0, sizeof(GF_SceneLoader)); - load.fileName = path; - load.ctx = m_pSm; - if (strstr(path, ".mp4") || strstr(path, ".MP4") ) load.isom = gf_isom_open(path, GF_ISOM_OPEN_READ, NULL); - gf_sm_load_init(&load); - gf_sm_load_run(&load); - gf_sm_load_done(&load); - if (load.isom) gf_isom_delete(load.isom); - - /* SceneManager should be initialized and filled correctly */ - - gf_sg_set_scene_size_info(m_pIs->graph, m_pSm->scene_width, m_pSm->scene_height, m_pSm->is_pixel_metrics); - - // TODO : replace with GetBifsStream - GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0); - - if (sc->streamType == 3) { - GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0); - GF_Command *c = (GF_Command *) gf_list_get(au->commands,0); - //gf_sg_command_apply(m_pIs->graph, c, 0); - /* This is a patch to solve the save pb: - When ApplyCommand is made on a Scene Replace Command - The command node is set to NULL - When we save a BIFS stream whose first command is of this kind, - the file saver thinks the bifs commands should come from an NHNT file - This is a temporary patch */ - if (c->tag == GF_SG_SCENE_REPLACE) { c->node = m_pIs->graph->RootNode; } - } - - gf_sc_set_scene(term->compositor, m_pIs->graph); - m_pIs->graph_attached = 1; - - // TODO : read actual values from file - SetLength(50); - SetFrameRate(25); - - // retrieves all the node from the tree and adds them to the node pool - GF_Node * root = gf_sg_get_root_node(m_pIs->graph); -// CreateDictionnary(); -} - -void V4SceneManager::SaveFile(const char *path) -{ - GF_SMEncodeOptions opts; - char rad_name[5000]; - - /* First dump the scene in a BT file */ - strcpy(rad_name, "dump"); - m_pSm->scene_graph->RootNode = NULL; - gf_sm_dump(m_pSm, rad_name, 0); - - /* Then reload properly (overriding the current SceneManager)*/ - GF_SceneLoader load; - memset(&load, 0, sizeof(GF_SceneLoader)); - load.fileName = "dump.bt"; - load.ctx = m_pSm; - gf_sm_load_init(&load); - gf_sm_load_run(&load); - gf_sm_load_done(&load); - - /* Finally encode the file */ - GF_ISOFile *mp4 = gf_isom_open(path, GF_ISOM_WRITE_EDIT, NULL); - m_pSm->max_node_id = gf_sg_get_max_node_id(m_pSm->scene_graph); - memset(&opts, 0, sizeof(opts)); - opts.flags = GF_SM_LOAD_MPEG4_STRICT; - gf_sm_encode_to_file(m_pSm, mp4, &opts); - gf_isom_set_brand_info(mp4, GF_ISOM_BRAND_MP42, 1); - gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_ISOM, 1); - gf_isom_close(mp4); -} - -void V4SceneManager::SetSceneSize(int w, int h) -{ - gf_sg_set_scene_size_info(m_pIs->graph, w,h, 1); - /*reassign scene graph to update scene size in renderer*/ - gf_sc_set_scene(m_gpac_panel->GetMPEG4Terminal()->compositor, m_pIs->graph); - m_pIs->graph_attached = 1; -} - -void V4SceneManager::GetSceneSize(wxSize &size) -{ - gf_sg_get_scene_size_info(m_pIs->graph, (u32 *)&(size.x), (u32 *)&(size.y)); -} - -GF_Node *V4SceneManager::SetTopNode(u32 tag) -{ - GF_Node *root = NewNode(tag); - gf_sg_set_root_node(m_pIs->graph, root); - GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0); - if (sc->streamType == 3) { - GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0); - GF_Command *c = (GF_Command *) gf_list_get(au->commands,0); - /* This is a patch to solve the save pb: - When ApplyCommand is made on a Scene Replace Command - The command node is set to NULL - When we save a BIFS stream whose first command is of this kind, - the file saver thinks the bifs commands should come from an NHNT file - This is a temporary patch */ - if (c->tag == GF_SG_SCENE_REPLACE) { - c->node = m_pIs->graph->RootNode; - gf_node_register(m_pIs->graph->RootNode, NULL); - } - } - return root; -} - -GF_Node *V4SceneManager::NewNode(u32 tag) -{ - GF_Node *n = gf_node_new(m_pIs->graph, tag); - if (!n) return NULL; - gf_node_init(n); - return n; -} - -GF_Node *V4SceneManager::CopyNode(GF_Node *node, GF_Node *parent, bool copy) -{ - if (copy) return CloneNodeForEditing(m_pIs->graph, node); - u32 nodeID = gf_node_get_id(node); - if (!nodeID) { - nodeID = gf_sg_get_next_available_node_id(m_pIs->graph); - gf_node_set_id(node, nodeID, NULL); - gf_node_register(node, parent); - } - return node; -} - -extern "C" { - -GF_Node *CloneNodeForEditing(GF_SceneGraph *inScene, GF_Node *orig) //, GF_Node *cloned_parent) -{ - u32 i, j, count; - GF_Node *node, *child, *tmp; - GF_ChildNodeItem *list, *list2; - GF_FieldInfo field_orig, field; - - /*this is not a mistake*/ - if (!orig) return NULL; - - /*check for DEF/USE - if (orig->sgprivate->NodeID) { - node = gf_sg_find_node(inScene, orig->sgprivate->NodeID); - //node already created, USE - if (node) { - gf_node_register(node, cloned_parent); - return node; - } - } - */ - /*create a node*/ -/* - if (orig->sgprivate->tag == TAG_MPEG4_ProtoNode) { - proto_node = ((GF_ProtoInstance *)orig)->proto_interface; - //create the instance but don't load the code -c we MUST wait for ISed routes to be cloned before - node = gf_sg_proto_create_node(inScene, proto_node, (GF_ProtoInstance *) orig); - } else { -*/ - node = gf_node_new(inScene, gf_node_get_tag(orig)); -// } - - count = gf_node_get_field_count(orig); - - /*copy each field*/ - for (i=0; isgprivate->NodeID) { - Node_SetID(node, orig->sgprivate->NodeID); - gf_node_register(node, cloned_parent); - }*/ - - /*init node before creating ISed routes so the eventIn handler are in place*/ - if (gf_node_get_tag(node) != TAG_ProtoNode) gf_node_init(node); - - return node; -} - -} // extern "C" - - -// GetBifsStream -- gets the first stream with id = 3 -GF_StreamContext * V4SceneManager::GetBifsStream() { - GF_StreamContext * ctx = NULL; - u32 count = gf_list_count(m_pSm->streams); - - // cycle trough each stream - while (count--) { - ctx = (GF_StreamContext *) gf_list_get(m_pSm->streams, count); - if (ctx->streamType == 3) break; - } - - if (ctx == NULL) return NULL; - - // if we went through the loop without finding any BIFS stream return null - if (ctx->streamType != 3) return NULL; - - return ctx; -} - - -// CreateDictionnary -- Create the root node of the dictionnary and populates it -void V4SceneManager::CreateDictionnary() { - GF_Node * root = gf_sg_get_root_node(m_pIs->graph); - dictionnary = NewNode(TAG_MPEG4_Switch); - - // Insert the dictionnary in the scene and gives it a name - gf_node_insert_child(root, dictionnary, 0); - gf_node_register(dictionnary, root); - gf_node_set_id(dictionnary, gf_sg_get_next_available_node_id(m_pIs->graph), DICTNAME); - - // makes the dictionnary invisible - // the number 1 field is the "whichChoice", setting it to -1 makes it display nothing - GF_FieldInfo field; - gf_node_get_field(dictionnary, 1, &field); - frame->GetFieldView()->SetFieldValue(field, &wxString("-1"), -1); // TODO : maybe put the method SetFieldValue somewhere more accessible - - // populates dictionnary with the root node of the scene - AddToDictionnary(root); -} - - -// AddToDictionnary -- adds a node to the dictionnary, increases its reference count, the node must already have an ID -// WARNING : does not add the node to the pool if it has a parent in the dictionnary -void V4SceneManager::AddToDictionnary(GF_Node * node) { - - // checks if nodes has a parent with an id - // if true then there is already a reference to this node - if (HasDefParent(node)) return; - - AddRecursive(node); -} - - -// AddRecursive -- recursively adds items with an ID to the dictionnary -void V4SceneManager::AddRecursive(GF_Node * node, bool parentAdded) { - - // skips empty nodes - if (!node) return; - - // skips the dictionnary - const char * c = gf_node_get_name(node); - if ( (c != NULL) && (!strcmp(c, DICTNAME)) ) return; - - // if node as an id adds it to the dictionnary and the node pool - u32 id = gf_node_get_id(node); - if (id) { - pools.Add(node); - // children of added node are not added to the dictionnary - if (!parentAdded) AddEffective(node); - parentAdded = true; - } - - GF_FieldInfo field; - GF_ChildNodeItem * list; - int count = gf_node_get_field_count(node); - - // tests all fields, if a field is a node then adds it and process its children recursively - for (int i=0; iGetTimeLine()->SetLength(length_); -} \ No newline at end of file diff --git a/applications/v4studio/V4SceneManager.h b/applications/v4studio/V4SceneManager.h deleted file mode 100644 index 3cb4209..0000000 --- a/applications/v4studio/V4SceneManager.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef _V4SceneManager_H -#define _V4SceneManager_H - -#include "safe_include.h" -#include -#include -#include // MPEG4CLIENT -#include "wxGPACPanel.h" -#include "V4NodePools.h" - - -#include - - -#define DICTNAME "__V4dictionnary" - - -class V4StudioFrame; - -extern "C" { - GF_Node *CloneNodeForEditing(GF_SceneGraph *inScene, GF_Node *orig); - int GetNextNodeID(GF_SceneGraph *sg); -} - -class V4SceneManager { -public: - // Constructor / Desctructor - V4SceneManager(V4StudioFrame *parent); - ~V4SceneManager(); - - // reusable nodes, sorted by tag - V4NodePools pools; - - /* file management functions */ - - void SaveFile(const char * path); - - void LoadCommon(); - void LoadNew(); - void LoadFile(const char *path); - - /* Node management functions */ - - GF_Node *NewNode(u32 tag); - GF_Node *CopyNode(GF_Node *node, GF_Node *parent, bool copy); - GF_Node *SetTopNode(u32 tag); // TODO : will destroy dictionnary - - void CreateIDandAddToPool(GF_Node *node); - - /* Dictionnary functions */ - - // adds a node to the dictionnary, increases its reference count, the node must already have an ID - void AddToDictionnary(GF_Node * node); - - // removes a node from the dictionnary = DELETES it's ID - void RemoveFromDictionnary(GF_Node * node); - - GF_Node * GetDictionnary() const; - - - /* Various */ - - void LoadCommand(u32 commandNumber); // ? - GF_StreamContext * GetBifsStream(); // Get the first stream with id = 3 - - - /* access to private members */ - - // SceneSize - void SetSceneSize(int w, int h); - void GetSceneSize(wxSize &size); - - // FrameRate - void SetFrameRate(const u32 framerate_) { frameRate = framerate_; } - u32 GetFrameRate() const { return frameRate; } - - // accesses Length - void SetLength(const u32 length_); - u32 GetLength() const { return length; } - - // accesses units - void SetUnits(u32 units_) { units = units_; } - u32 GetUnits() const { return units; } - - - - GF_Compositor *GetSceneCompositor() { return m_gpac_panel->GetSceneCompositor(); } - - // GF_InlineScene - GF_InlineScene *GetInlineScene() { return m_pIs; } - - // SceneGraph - GF_SceneGraph *GetSceneGraph() { return m_pIs->graph; } - GF_Node *GetRootNode() { return gf_sg_get_root_node(m_pIs->graph); } - - wxGPACPanel *GetGPACPanel() { return m_gpac_panel; } - V4StudioFrame *GetV4StudioFrame() { return frame; } - - // TODO : terminal - private: - - /* dictionnary function */ - - // initializes the dictionnary node - void CreateDictionnary(); - - // Finds all node with an ID from the given node and adds them to the node pool and the dictionnary - void AddRecursive(GF_Node * node, bool parentAdded = false); - - // calls a proper function to add the node according to its type - void AddEffective(GF_Node * node); - - // Create a dummy node of type tag and it to the specified field (or reimplace if the field is single valued) - GF_Node * CreateDummyNode(const u32 tag, GF_Node * parent, const u32 fieldIndex); - - // Sets the first node as a child of the second using the given field - void MakeChild(GF_Node * child, GF_Node * parent, const u32 fieldIndex); - - // Checks is specified node as a parent with an ID - GF_Node * V4SceneManager::HasDefParent(GF_Node * node); - - // adds a node to the dictionnary - void AddGen(GF_Node * node); - void AddGeometry(GF_Node * node); - void AddAppearance(GF_Node * node); - void AddTexture(GF_Node * node); - void AddMaterial(GF_Node * node); - - -protected: - - // self created - LPINLINESCENE m_pIs; - GF_SceneManager *m_pSm; - GF_Node *dictionnary; - wxGPACPanel *m_gpac_panel; - - // from other objects - V4StudioFrame *frame; - - u8 frameRate; - u32 length; // in frames! - u32 units; // = 1000 - -}; - -#endif - diff --git a/applications/v4studio/V4Service.cpp b/applications/v4studio/V4Service.cpp deleted file mode 100644 index 34bf3bc..0000000 --- a/applications/v4studio/V4Service.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include "V4Service.h" - -#include - -#define V4_PRIVATE_SCENE_OTI 0xFF - -extern "C" { - - -V4Channel *V4Service::V4_GetChannel(V4Service *v4service, LPNETCHANNEL ch) -{ - u32 i; - for (i=0; ichannels); i++) { - V4Channel *v4c = (V4Channel *)gf_list_get(v4service->channels, i); - if (v4c->ch && v4c->ch==ch) return v4c; - } - return NULL; -} - -Bool V4Service::V4_RemoveChannel(V4Service *v4service, LPNETCHANNEL ch) -{ - u32 i; - for (i=0; ichannels); i++) { - V4Channel *v4c = (V4Channel *)gf_list_get(v4service->channels, i); - if (v4c->ch && v4c->ch==ch) { - gf_list_rem(v4service->channels, i); - gf_free(v4c); - return 1; - } - } - return 0; -} - -static Bool V4_CanHandleURL(GF_InputService *plug, const char *url) -{ - return 1; -} - -static GF_Err V4_ConnectService (GF_InputService *plug, GF_ClientService *serv, const char *url) -{ - V4Service *v4serv = (V4Service *)plug->priv; - v4serv->SetService(serv); - gf_term_on_connect(v4serv->GetService(), NULL, GF_OK); - return GF_OK; -} - -static GF_Err V4_CloseService(GF_InputService *plug) -{ - V4Service *v4serv = (V4Service *)plug->priv; - gf_term_on_disconnect(v4serv->GetService(), NULL, GF_OK); - return GF_OK; -} - -static GF_Descriptor *V4_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url) -{ - V4Service *v4service= (V4Service *) plug->priv; - GF_ESD *esd; - GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor *) gf_odf_desc_new(GF_ODF_IOD_TAG); - iod->scene_profileAndLevel = 1; - iod->graphics_profileAndLevel = 1; - iod->OD_profileAndLevel = 1; - iod->audio_profileAndLevel = 0xFE; - iod->visual_profileAndLevel = 0xFE; - iod->objectDescriptorID = 1; - - esd = gf_odf_desc_esd_new(0); - esd->slConfig->timestampResolution = 1000; - esd->slConfig->useTimestampsFlag = 1; - esd->ESID = 0xFFFE; - esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE; - esd->decoderConfig->objectTypeIndication = 0x01; //V4_PRIVATE_SCENE_OTI; - if (v4service->GetPath()) { - esd->decoderConfig->decoderSpecificInfo->dataLength = strlen(v4service->GetPath()) + 1; - esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(v4service->GetPath()); - } - gf_list_add(iod->ESDescriptors, esd); - return (GF_Descriptor *)iod; -} - -static GF_Err V4_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) -{ - u32 ESID; - V4Service *v4serv = (V4Service *)plug->priv; - - sscanf(url, "ES_ID=%ud", &ESID); - if (!ESID) { - gf_term_on_connect(v4serv->GetService(), channel, GF_STREAM_NOT_FOUND); - } else { - V4Channel *v4c = (V4Channel *)gf_malloc(sizeof(V4Channel)); - memset(v4c, 0, sizeof(V4Channel)); - v4c->ch = channel; - v4c->ESID = ESID; - gf_list_add(v4serv->GetChannels(), v4c); - gf_term_on_connect(v4serv->GetService(), channel, GF_OK); - } - return GF_OK; -} - -static GF_Err V4_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) -{ - V4Service *v4serv = (V4Service *)plug->priv; - Bool had_ch; - - had_ch = v4serv->V4_RemoveChannel(v4serv, channel); - gf_term_on_disconnect(v4serv->GetService(), channel, had_ch ? GF_OK : GF_STREAM_NOT_FOUND); - return GF_OK; -} - -static GF_Err V4_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) -{ - V4Service *v4serv = (V4Service *)plug->priv; - V4Channel *v4c; - - if (!com->base.on_channel) return GF_OK; - - v4c = v4serv->V4_GetChannel(v4serv, com->base.on_channel); - if (!v4c) return GF_STREAM_NOT_FOUND; - - switch (com->command_type) { - case GF_NET_CHAN_SET_PULL: return GF_OK; - case GF_NET_CHAN_INTERACTIVE: return GF_OK; - case GF_NET_CHAN_SET_PADDING: return GF_NOT_SUPPORTED; - case GF_NET_CHAN_BUFFER: - com->buffer.max = com->buffer.min = 0; - return GF_OK; - case GF_NET_CHAN_DURATION: - /*this is not made for updates, use undefined duration*/ - com->duration.duration = 0; - return GF_OK; - case GF_NET_CHAN_PLAY: - v4c->start = (u32) (1000 * com->play.start_range); - v4c->end = (u32) (1000 * com->play.end_range); - return GF_OK; - case GF_NET_CHAN_STOP: - return GF_OK; - case GF_NET_CHAN_CONFIG: return GF_OK; - case GF_NET_CHAN_GET_DSI: - com->get_dsi.dsi = NULL; - com->get_dsi.dsi_len = 0; - return GF_OK; - } - return GF_OK; -} - -static GF_Err V4_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data) -{ - V4Channel *v4c; - V4Service *v4serv = (V4Service *)plug->priv; - v4c = v4serv->V4_GetChannel(v4serv, channel); - if (!v4c) return GF_STREAM_NOT_FOUND; - - memset(out_sl_hdr, 0, sizeof(GF_SLHeader)); - out_sl_hdr->compositionTimeStampFlag = 1; - out_sl_hdr->compositionTimeStamp = v4c->start; - out_sl_hdr->accessUnitStartFlag = 1; - *sl_compressed = 0; - *out_reception_status = GF_OK; - *is_new_data = 1; - return GF_OK; return GF_OK; -} - -static GF_Err V4_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) -{ - return GF_OK; -} - -static Bool V4_CanHandleURLInService(GF_InputService *plug, const char *url) -{ - return 0; -} - -} // extern "C" - -V4Service::V4Service(const char *path) -{ - - m_pNetClient = (GF_InputService *)gf_malloc(sizeof(GF_InputService)); - m_pNetClient->priv = this; - - m_pNetClient->CanHandleURL = V4_CanHandleURL; - - m_pNetClient->ConnectService = V4_ConnectService; - m_pNetClient->CloseService = V4_CloseService; - - m_pNetClient->ConnectChannel = V4_ConnectChannel; - m_pNetClient->DisconnectChannel = V4_DisconnectChannel; - - m_pNetClient->GetServiceDescriptor = V4_GetServiceDesc; - m_pNetClient->ServiceCommand = V4_ServiceCommand; - - m_pNetClient->ChannelGetSLP = V4_ChannelGetSLP; - m_pNetClient->ChannelReleaseSLP = V4_ChannelReleaseSLP; - - m_pNetClient->CanHandleURLInService = V4_CanHandleURLInService; - - channels = gf_list_new(); - if (path) m_path = gf_strdup(path); -} - -V4Service::~V4Service() -{ - if (m_path) gf_free(m_path); - gf_list_del(channels); - gf_free(m_pNetClient); -} diff --git a/applications/v4studio/V4Service.h b/applications/v4studio/V4Service.h deleted file mode 100644 index 183a367..0000000 --- a/applications/v4studio/V4Service.h +++ /dev/null @@ -1,42 +0,0 @@ -#include "safe_include.h" -#include - -typedef struct -{ - u32 ESID; - LPNETCHANNEL ch; - u32 start, end; -} V4Channel; - - -class V4Service { -public: - - V4Service(const char*path); - ~V4Service(); - - void SetService(GF_ClientService *s) { m_pService = s; } - GF_ClientService *GetService() { return m_pService; } - - void SetPath(char *path) { m_path = path; } - char *GetPath() { return m_path; } - - GF_List* GetChannels() { return channels; } - V4Channel *V4_GetChannel(V4Service *v4service, LPNETCHANNEL ch); - Bool V4_RemoveChannel(V4Service *v4service, LPNETCHANNEL ch); - - GF_InputService *GetServiceInterface() { return m_pNetClient; } - -protected: - - /* the interface given to the GPAC Core */ - GF_InputService *m_pNetClient; - - /* The actual GPAC Core service returned by the interface */ - GF_ClientService *m_pService; - /* All the channels of the current service */ - GF_List *channels; - - /* The path to the currently load file */ - char *m_path; -}; \ No newline at end of file diff --git a/applications/v4studio/V4StudioApp.cpp b/applications/v4studio/V4StudioApp.cpp deleted file mode 100644 index 32fef26..0000000 --- a/applications/v4studio/V4StudioApp.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "safe_include.h" - -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include "V4StudioApp.h" -#include "V4StudioFrame.h" -#include -//#include - -IMPLEMENT_APP(V4StudioApp) - -bool V4StudioApp::OnInit() -{ - wxFrame *frame = new V4StudioFrame(); - frame->Show(TRUE); - SetTopWindow(frame); - return true; -} - diff --git a/applications/v4studio/V4StudioApp.h b/applications/v4studio/V4StudioApp.h deleted file mode 100644 index fe70266..0000000 --- a/applications/v4studio/V4StudioApp.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _V4STUDIO_APP_H -#define _V4STUDIO_APP_H - -class V4StudioApp : public wxApp -{ -public: - virtual bool OnInit(); -protected: -private: -}; - -DECLARE_APP(V4StudioApp) - -#endif - diff --git a/applications/v4studio/V4StudioFrame.cpp b/applications/v4studio/V4StudioFrame.cpp deleted file mode 100644 index d51a78e..0000000 --- a/applications/v4studio/V4StudioFrame.cpp +++ /dev/null @@ -1,951 +0,0 @@ -#include "safe_include.h" - -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include "V4StudioFrame.h" -#include "wx/xrc/xmlres.h" - - -#include -#include // GF_Terminal -#include - -V4StudioFrame::V4StudioFrame(): - wxFrame((wxFrame *) NULL, -1, "V4Studio", wxPoint(50, 50), wxSize(800, 700)) -{ - - m_pV4sm = NULL; - - m_selection = NULL; - m_parentSelection = NULL; - m_clipboardNode = NULL; - - m_frame = 0; // we start at frame=0 - editDict = false; - - // Creates components and places them on the form - fieldView = new V4FieldList(this, wxSize(100,250)); - treeView = new V4StudioTree(this, wxSize(100,250), fieldView); - timeLine = new V4TimeLine(this); - timeLine->SetSize(500, 100); - cmdPanel = new V4CommandPanel(this); - cmdPanel->SetSize(100, 100); - - /*new m_pFileMenu bar*/ - wxMenuBar *b = new wxMenuBar(); - /*file*/ - m_pFileMenu = new wxMenu(); - m_pFileMenu->Append(MENU_FILE_NEW, "&New\tCtrl+N", "Create a new document"); - m_pFileMenu->Append(MENU_FILE_OPEN, "&Open...\tCtrl+O", "Open an existing document"); - m_pFileMenu->Append(MENU_FILE_SAVE, "&Save\tCtrl+S", "Save the active document"); - m_pFileMenu->Append(MENU_FILE_CLOSE, "&Close\tCtrl+X", "Close the active document"); - m_pFileMenu->AppendSeparator(); - m_pFileMenu->Append(CHANGE_SIZE_DIALOG, "&Size\tCtrl+Z", "Change scene size"); - m_pFileMenu->Append(CHANGE_FRAMERATE, "&FrameRate\tCtrl+F", "Change FrameRate"); - m_pFileMenu->Append(CHANGE_LENGTH, "&Length\tCtrl+L", "Change Length"); - m_pFileMenu->AppendSeparator(); - m_pFileMenu->Append(MENU_FILE_QUIT, "E&xit", "Quit the application; prompts to save documents"); - b->Append(m_pFileMenu, "&File"); - SetMenuBar(b); - - /*file*/ - m_pToolsMenu = new wxMenu(); - m_pToolsMenu->Append(MENU_TOOL_SHOW_LOWLEVEL, "&Low-Level\tCtrl+L", "Shows the low-level toolbar"); - m_pToolsMenu->Append(MENU_TOOL_SHOW_HIGHLEVEL, "&High-Level\tCtrl+H", "Shows the high-level toolbar"); - b->Append(m_pToolsMenu, "&Tools"); - SetMenuBar(b); - - m_pStatusbar = CreateStatusBar(); - - // Main Toolbar - m_pMainToolbar = new wxToolBar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL|wxTB_FLAT); - m_pMainToolbar->AddTool(TOOL_FILE_NEW, _("New"), wxBitmap (wxT("rc\\new.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Open a new file"), wxT("")); - m_pMainToolbar->AddTool(TOOL_FILE_OPEN, _("Open"), wxBitmap (wxT("rc\\open.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Open an existing file (BT/XMT/MP4)"), wxT("")); - m_pMainToolbar->AddTool(TOOL_FILE_SAVE, _("Save"), wxBitmap (wxT("rc\\save.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Save to a file"), wxT("")); - m_pMainToolbar->AddTool(TOOL_FILE_CLOSE, _("Close"), wxBitmap (wxT("rc\\close.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Close the file"), wxT("")); - m_pMainToolbar->AddSeparator(); - m_pMainToolbar->AddTool(TOOL_FILE_PREVIEW, _("Preview"), wxBitmap (wxT("rc\\preview.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Preview in player"), wxT("")); - m_pMainToolbar->AddSeparator(); - m_pMainToolbar->AddTool(TOOL_EDIT_CUT, _("Cut"), wxBitmap (wxT("rc\\cut.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Cut"), wxT("")); - m_pMainToolbar->AddTool(TOOL_EDIT_COPY, _("Copy"), wxBitmap (wxT("rc\\copy.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Copy"), wxT("")); - m_pMainToolbar->AddTool(TOOL_EDIT_PASTE, _("Paste"), wxBitmap (wxT("rc\\paste.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Paste"), wxT("")); - m_pMainToolbar->AddTool(TOOL_EDIT_PASTE_USE, _("PastePlus"), wxBitmap (wxT("rc\\paste_use.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Paste a USE"), wxT("")); - m_pMainToolbar->AddTool(TOOL_EDIT_DELETE, _("Delete"), wxBitmap (wxT("rc\\delete.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Delete"), wxT("")); - m_pMainToolbar->AddSeparator(); - m_pMainToolbar->AddTool(TOOL_EDIT_UNDO, _("Undo"), wxBitmap (wxT("rc\\undo.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Undo"), wxT("")); - m_pMainToolbar->AddTool(TOOL_EDIT_REDO, _("Redo"), wxBitmap (wxT("rc\\redo.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Redo"), wxT("")); - m_pMainToolbar->AddSeparator(); - - m_pMainToolbar->AddSeparator(); - - m_pMainToolbar->AddTool(TOOL_ADD_TO_TL, _("AddToTL"), wxBitmap( wxT("rc\\paste.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Add to timeLine"), wxT("")); - m_pMainToolbar->AddTool(TOOL_NEXT_FRAME, _("NextFrame"), wxBitmap( wxT("rc\\redo.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Next frame"), wxT("")); - m_pMainToolbar->AddTool(TOOL_VIEW_DICT, _("ViewDict"), wxBitmap( wxT("rc\\open.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("View Dictionnary"), wxT("")); - - /* Not Implemented yet */ - m_pMainToolbar->EnableTool(TOOL_FILE_PREVIEW, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_UNDO, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_REDO, false); - m_pMainToolbar->EnableTool(TOOL_NEXT_FRAME, false); - - /* Not available when starting V4Studio */ - /* Nothing to save */ - m_pFileMenu->Enable(MENU_FILE_SAVE, false); - m_pFileMenu->Enable(MENU_FILE_CLOSE, false); - m_pFileMenu->Enable(CHANGE_SIZE_DIALOG, false); - m_pFileMenu->Enable(CHANGE_LENGTH, false); - m_pFileMenu->Enable(CHANGE_FRAMERATE, false); - m_pMainToolbar->EnableTool(TOOL_FILE_SAVE, false); - m_pMainToolbar->EnableTool(TOOL_FILE_CLOSE, false); - - /* Nothing to edit */ - m_pMainToolbar->EnableTool(TOOL_EDIT_CUT, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_COPY, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE_USE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_DELETE, false); - - m_pMainToolbar->EnableTool(TOOL_ADD_TO_TL, false); - m_pMainToolbar->EnableTool(TOOL_VIEW_DICT, false); - m_pMainToolbar->Realize(); - SetToolBar(m_pMainToolbar); - - m_uSelectedNodeToolBar = 0; - // Node Creation Toolbar - m_pLowLevelNodeToolbar = new wxToolBar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_VERTICAL|wxTB_FLAT); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_ORDEREDGROUP, _("OrderedGroup"), wxBitmap (wxT("rc\\orderedgroup.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create an OrderedGroup"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_LAYER2D, _("Layer2D"), wxBitmap (wxT("rc\\layer2d.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Layer2D"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_TRANSFORM2D, _("Transform2D"), wxBitmap (wxT("rc\\t2d.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Tranform2D"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_TRANSFORMMATRIX2D, _("TransformMatrix2D"), wxBitmap (wxT("rc\\tm2d.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a TranformMatrix2D"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_COLOR_TRANSFORM, _("ColorTransform"), wxBitmap (wxT("rc\\colortransform.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a ColorTransform"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_SHAPE, _("Shape"), wxBitmap (wxT("rc\\shape.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Shape"), wxT("")); - m_pLowLevelNodeToolbar->AddSeparator(); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_APPEARANCE, _("Appearance"), wxBitmap (wxT("rc\\appearance.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create an Appearance"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_MATERIAL2D, _("Material2D"), wxBitmap (wxT("rc\\material2d.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Material2D"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_LINEPROPS, _("LineProps"), wxBitmap (wxT("rc\\lineproperties.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a LineProperties"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_LINEAR_GRADIENT, _("LinearGradient"), wxBitmap (wxT("rc\\lg.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Linear Gradient"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_RADIAL_GRADIENT, _("RadialGradient"), wxBitmap (wxT("rc\\rg.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Radial Gradient"), wxT("")); - m_pLowLevelNodeToolbar->AddSeparator(); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_RECT, _("Rectangle"), wxBitmap (wxT("rc\\rect.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Rectangle"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_CIRCLE, _("Circle"), wxBitmap (wxT("rc\\circle.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Rectangle"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_IFS2D, _("IndexedFaceSet2D"), wxBitmap (wxT("rc\\ifs2d.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create an IndexedFaceSet2D"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_ILS2D, _("IndexedLineSet2D"), wxBitmap (wxT("rc\\ils2d.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create an IndexedLineSet2D"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_XLINEPROPS, _("XLineProps"), wxBitmap (wxT("rc\\xlineproperties.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create an XLineProperties"), wxT("")); - m_pLowLevelNodeToolbar->AddSeparator(); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_TEXT, _("Text"), wxBitmap (wxT("rc\\text.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a Text"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_FONTSTYLE, _("FontStyle"), wxBitmap (wxT("rc\\fs.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Create a FontStyle"), wxT("")); - m_pLowLevelNodeToolbar->AddSeparator(); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_BACKGROUND2D, _("Background2D"), wxBitmap (wxT("rc\\image.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Add a Background2D"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_MOVIE, _("Movie"), wxBitmap (wxT("rc\\movie.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Add a Movie"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_IMAGE, _("Image"), wxBitmap (wxT("rc\\image.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Add an Image"), wxT("")); - m_pLowLevelNodeToolbar->AddTool(TOOL_NEW_SOUND, _("Sound"), wxBitmap (wxT("rc\\sound.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Add a Sound"), wxT("")); - m_pLowLevelNodeToolbar->Realize(); - -/* - m_pHighLevelNodeToolbar = new wxToolBar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_VERTICAL|wxTB_FLAT); - m_pHighLevelNodeToolbar->AddTool(TOOL_NEW_2DSCENE, _("OrderedGroup"), wxBitmap (wxT("rc\\orderedgroup.bmp"), wxBITMAP_TYPE_ANY), wxNullBitmap, wxITEM_NORMAL, _("Creates a 2D scene"), wxT("")); - m_pHighLevelNodeToolbar->Realize(); -*/ - set_properties(); - do_layout(); - UpdateToolBar(); -} - -V4StudioFrame::~V4StudioFrame() -{ -} - - -/* Functions that changes scene parameters */ - -void V4StudioFrame::OnChangeFrameRate(wxCommandEvent &event) { - if (!m_pV4sm) return; - - u32 l = m_pV4sm->GetFrameRate(); - wxString sFR; - sFR.Printf("%d", l); - - wxTextEntryDialog dialog(this, _T("Enter scene framerate"), _T("one positive integer number"), sFR, wxOK | wxCANCEL); - - if (dialog.ShowModal() != wxID_OK) { - dialog.Destroy(); - return; - } - - sscanf(dialog.GetValue(), "%d", &l); - m_pV4sm->SetFrameRate(l); - - dialog.Destroy(); - SceneGraphChanged(); -} - - -void V4StudioFrame::OnChangeLength(wxCommandEvent &event) { - if (!m_pV4sm) return; - u32 l = m_pV4sm->GetLength(); - wxString sLength; - sLength.Printf("%d", l); - - wxTextEntryDialog dialog(this, _T("Enter scene length"), _T("one positive integer number"), sLength, wxOK | wxCANCEL); - - if (dialog.ShowModal() != wxID_OK) { - dialog.Destroy(); - return; - } - - sscanf(dialog.GetValue(), "%d", &l); - m_pV4sm->SetLength(l); - - dialog.Destroy(); - SceneGraphChanged(); -} - -void V4StudioFrame::OnChangeSize(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - u32 w, h; - wxSize sceneSize; - m_pV4sm->GetSceneSize(sceneSize); - w = sceneSize.GetX(); - h = sceneSize.GetY(); - wxString sSize; - sSize.Printf("%d %d", w, h); - wxTextEntryDialog dialog(this, - _T("Enter the scene width and height"), - _T("Please enter two integer numbers"), - sSize, - wxOK | wxCANCEL); - - while (dialog.ShowModal() != wxID_OK && w == 0 && h == 0) {} - sscanf(dialog.GetValue(), "%d %d", &w, &h); - m_pV4sm->SetSceneSize(w,h); - dialog.Destroy(); - SceneGraphChanged(); -} - -// Dispatchs the new scene graph to all the sub components who need it. -void V4StudioFrame::SceneGraphChanged() -{ - m_parentSelection = NULL; - m_selection = (!m_pV4sm ? NULL : m_pV4sm->GetRootNode()); - Layout(); - Update(); -} - -void V4StudioFrame::set_properties() -{ - SetTitle(_("V4Studio")); - wxIcon _icon; - _icon.CopyFromBitmap(wxBitmap(_("rc\\v4.bmp"), wxBITMAP_TYPE_ANY)); - SetIcon(_icon); - SetSize(wxSize(500, 500)); -} - - -void V4StudioFrame::do_layout() -{ - wxBoxSizer * sizer_6 = new wxBoxSizer(wxVERTICAL); // top = treeview + fieldview; bottom = timeline + command panel - wxBoxSizer * sizer_7 = new wxBoxSizer(wxHORIZONTAL); // right = timeline, left = command panel - wxBoxSizer * sizer_8 = new wxBoxSizer(wxHORIZONTAL); // right = treeview; left = fieldview - - sizer_6->Add(sizer_8, 2, wxEXPAND, 0); // height of treeview twice bigger thant height of timeline - sizer_6->Add(sizer_7, 1, wxEXPAND, 0); - - sizer_7->Add(timeLine, 3, wxEXPAND, 0); - sizer_7->Add(cmdPanel, 1, wxEXPAND, 0); - - sizer_8->Add(treeView, 1, wxEXPAND, 0); - sizer_8->Add(fieldView, 1, wxEXPAND, 0); - - wxBoxSizer* sizer_9 = new wxBoxSizer(wxHORIZONTAL); - - sizer_9->Add(m_pLowLevelNodeToolbar, 0, wxEXPAND, 0); -/* - if (m_uSelectedNodeToolBar == 0) sizer_9->Add(m_pLowLevelNodeToolbar, 0, wxEXPAND, 0); - else sizer_9->Add(m_pHighLevelNodeToolbar, 0, wxEXPAND, 0); -*/ - - sizer_9->Add(sizer_6, 1, wxEXPAND, 0); - - SetSizer(sizer_9); - Layout(); - - cmdPanel->Layout(); -} - - -BEGIN_EVENT_TABLE(V4StudioFrame, wxFrame) - // m_pFileMenu events - EVT_MENU(MENU_FILE_NEW, V4StudioFrame::OnNew) - EVT_MENU(MENU_FILE_OPEN, V4StudioFrame::OnFileOpen) - EVT_MENU(MENU_FILE_SAVE, V4StudioFrame::OnSave) - EVT_MENU(MENU_FILE_CLOSE, V4StudioFrame::OnClose) - EVT_MENU(MENU_FILE_QUIT, V4StudioFrame::OnQuit) - EVT_MENU(CHANGE_SIZE_DIALOG, V4StudioFrame::OnChangeSize) - EVT_MENU(CHANGE_FRAMERATE, V4StudioFrame::OnChangeFrameRate) - EVT_MENU(CHANGE_LENGTH, V4StudioFrame::OnChangeLength) - - // m_pToolsMenu events - EVT_MENU(MENU_TOOL_SHOW_LOWLEVEL, V4StudioFrame::OnLowLevelTools) - EVT_MENU(MENU_TOOL_SHOW_HIGHLEVEL, V4StudioFrame::OnHighLevelTools) - - // edit toolbar events - EVT_TOOL(TOOL_FILE_NEW, V4StudioFrame::OnNew) - EVT_TOOL(TOOL_FILE_OPEN, V4StudioFrame::OnFileOpen) - EVT_TOOL(TOOL_FILE_SAVE, V4StudioFrame::OnSave) - EVT_TOOL(TOOL_FILE_CLOSE, V4StudioFrame::OnClose) - EVT_TOOL(TOOL_EDIT_CUT, V4StudioFrame::OnEditCut) - EVT_TOOL(TOOL_EDIT_COPY, V4StudioFrame::OnEditCopy) - EVT_TOOL(TOOL_EDIT_PASTE, V4StudioFrame::OnEditPaste) - EVT_TOOL(TOOL_EDIT_PASTE_USE, V4StudioFrame::OnEditPasteUse) - EVT_TOOL(TOOL_EDIT_DELETE, V4StudioFrame::OnEditDelete) - EVT_TOOL(TOOL_ADD_TO_TL, V4StudioFrame::OnAddToTimeLine) - EVT_TOOL(TOOL_NEXT_FRAME, V4StudioFrame::NextFrame) - EVT_TOOL(TOOL_VIEW_DICT, V4StudioFrame::SwitchView) - - // new toolbar events - EVT_TOOL(TOOL_NEW_ORDEREDGROUP, V4StudioFrame::OnNewOrderedGroup) - EVT_TOOL(TOOL_NEW_LAYER2D, V4StudioFrame::OnNewLayer2D) - EVT_TOOL(TOOL_NEW_TRANSFORM2D, V4StudioFrame::OnNewTransform2D) - EVT_TOOL(TOOL_NEW_TRANSFORMMATRIX2D, V4StudioFrame::OnNewTransformMatrix2D) - EVT_TOOL(TOOL_NEW_COLOR_TRANSFORM, V4StudioFrame::OnNewColorTransform) - EVT_TOOL(TOOL_NEW_SHAPE, V4StudioFrame::OnNewShape) - EVT_TOOL(TOOL_NEW_APPEARANCE, V4StudioFrame::OnNewAppearance) - EVT_TOOL(TOOL_NEW_LINEAR_GRADIENT, V4StudioFrame::OnNewLinearGradient) - EVT_TOOL(TOOL_NEW_RADIAL_GRADIENT, V4StudioFrame::OnNewRadialGradient) - EVT_TOOL(TOOL_NEW_MATERIAL2D, V4StudioFrame::OnNewMaterial2D) - EVT_TOOL(TOOL_NEW_LINEPROPS, V4StudioFrame::OnNewLineProps) - EVT_TOOL(TOOL_NEW_XLINEPROPS, V4StudioFrame::OnNewXLineProps) - EVT_TOOL(TOOL_NEW_RECT, V4StudioFrame::OnNewRect) - EVT_TOOL(TOOL_NEW_CIRCLE, V4StudioFrame::OnNewCircle) - EVT_TOOL(TOOL_NEW_TEXT, V4StudioFrame::OnNewText) - EVT_TOOL(TOOL_NEW_FONTSTYLE, V4StudioFrame::OnNewFontStyle) - EVT_TOOL(TOOL_NEW_SOUND, V4StudioFrame::OnNewSound) - EVT_TOOL(TOOL_NEW_BACKGROUND2D, V4StudioFrame::OnNewBackground2D) - EVT_TOOL(TOOL_NEW_IMAGE, V4StudioFrame::OnNewImageTexture) - EVT_TOOL(TOOL_NEW_MOVIE, V4StudioFrame::OnNewMovieTexture) -END_EVENT_TABLE() - -// Creates New Scene -void V4StudioFrame::OnNew(wxCommandEvent &event) -{ - m_pV4sm = new V4SceneManager(this); - m_pV4sm->LoadNew(); - - m_pMainToolbar->EnableTool(TOOL_ADD_TO_TL, true); - m_pMainToolbar->EnableTool(TOOL_VIEW_DICT, true); - m_pMainToolbar->EnableTool(TOOL_FILE_SAVE, true); - m_pFileMenu->Enable(MENU_FILE_SAVE, true); - m_pMainToolbar->EnableTool(TOOL_FILE_CLOSE, true); - m_pFileMenu->Enable(MENU_FILE_CLOSE, true); - m_pMainToolbar->EnableTool(TOOL_FILE_OPEN, false); - m_pFileMenu->Enable(MENU_FILE_OPEN, false); - m_pMainToolbar->EnableTool(TOOL_FILE_NEW, false); - m_pFileMenu->Enable(MENU_FILE_NEW, false); - m_pFileMenu->Enable(CHANGE_SIZE_DIALOG, true); - m_pFileMenu->Enable(CHANGE_LENGTH, true); - m_pFileMenu->Enable(CHANGE_FRAMERATE, true); - - Layout(); - SetStatusText("New scene", 0); - SceneGraphChanged(); - - OnChangeSize(event); -} - -// Opens an existing file -void V4StudioFrame::OnFileOpen(wxCommandEvent &event) -{ - wxFileDialog *dlg = new wxFileDialog(this, "Open a bt scene", - "", "", "BT Files (*.bt)|*.bt|MP4 Files (*.mp4)|*.mp4|XMT Files (*.xmt)|*.xmt|SWF Files (*.swf)|*.swf|All files (*.*)|*.*", - wxOPEN, wxDefaultPosition); - if ( dlg->ShowModal() == wxID_OK ) { - if (m_pV4sm) delete m_pV4sm; - m_pV4sm = new V4SceneManager(this); - m_pV4sm->LoadFile(dlg->GetPath().c_str()); - - m_pMainToolbar->EnableTool(TOOL_ADD_TO_TL, true); - m_pMainToolbar->EnableTool(TOOL_VIEW_DICT, true); - m_pMainToolbar->EnableTool(TOOL_FILE_SAVE, true); - m_pFileMenu->Enable(MENU_FILE_SAVE, true); - m_pMainToolbar->EnableTool(TOOL_FILE_CLOSE, true); - m_pFileMenu->Enable(MENU_FILE_CLOSE, true); - m_pMainToolbar->EnableTool(TOOL_FILE_OPEN, false); - m_pFileMenu->Enable(MENU_FILE_OPEN, false); - m_pMainToolbar->EnableTool(TOOL_FILE_NEW, false); - m_pFileMenu->Enable(MENU_FILE_NEW, true); - m_pFileMenu->Enable(CHANGE_SIZE_DIALOG, true); - m_pFileMenu->Enable(CHANGE_LENGTH, true); - m_pFileMenu->Enable(CHANGE_FRAMERATE, true); - - Layout(); - SetStatusText(dlg->GetFilename(), 0); - SceneGraphChanged(); - } - dlg->Destroy(); -} - -void V4StudioFrame::OnSave(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - wxFileDialog *dlg = new wxFileDialog(this, "Save the scene to an mp4 file", - "", "", "MPEG-4 Files (*.mp4)|*.mp4|All files (*.*)|*.*", - wxSAVE, wxDefaultPosition); - if ( dlg->ShowModal() == wxID_OK ) - { - m_pV4sm->SaveFile(dlg->GetPath().c_str()); - SetStatusText(dlg->GetFilename(), 0); - } - dlg->Destroy(); -} - -void V4StudioFrame::OnClose(wxCommandEvent &event) -{ - if (m_pV4sm) delete m_pV4sm; - m_pV4sm = NULL; - - m_pMainToolbar->EnableTool(TOOL_ADD_TO_TL, false); - m_pMainToolbar->EnableTool(TOOL_VIEW_DICT, false); - m_pMainToolbar->EnableTool(TOOL_FILE_SAVE, false); - m_pFileMenu->Enable(MENU_FILE_SAVE, false); - m_pMainToolbar->EnableTool(TOOL_FILE_CLOSE, false); - m_pFileMenu->Enable(MENU_FILE_CLOSE, false); - m_pMainToolbar->EnableTool(TOOL_FILE_OPEN, true); - m_pFileMenu->Enable(MENU_FILE_OPEN, true); - m_pMainToolbar->EnableTool(TOOL_FILE_NEW, true); - m_pFileMenu->Enable(MENU_FILE_NEW, true); - m_pFileMenu->Enable(CHANGE_SIZE_DIALOG, false); - m_pFileMenu->Enable(CHANGE_LENGTH, false); - m_pFileMenu->Enable(CHANGE_FRAMERATE, false); - - m_clipboardNode = NULL; - m_clipboardParentNode = NULL; - m_pMainToolbar->EnableTool(TOOL_EDIT_CUT, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_COPY, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE_USE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_DELETE, false); - Layout(); - SceneGraphChanged(); -} - -// Quits application -// TODO : memory leaks ! -void V4StudioFrame::OnQuit(wxCommandEvent &event) -{ - Close(FALSE); -} - -/**********************************************/ -/* Tools Menu methods */ -/**********************************************/ -void V4StudioFrame::OnLowLevelTools(wxCommandEvent &event) -{ - m_uSelectedNodeToolBar = 0; - do_layout(); -} - -void V4StudioFrame::OnHighLevelTools(wxCommandEvent &event) -{ - m_uSelectedNodeToolBar = 1; - do_layout(); -} - -/**********************************************/ -/* Functions to add components to the scene */ -/**********************************************/ -void V4StudioFrame::OnNewOrderedGroup(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *top = m_pV4sm->GetRootNode(); - if (!top) { - top = m_pV4sm->SetTopNode(TAG_MPEG4_OrderedGroup); - m_selection = top; - m_parentSelection = NULL; - } else { - GF_Node *og = m_pV4sm->NewNode(TAG_MPEG4_OrderedGroup); - gf_node_insert_child(m_selection, og, -1); - gf_node_register(og, m_selection); - m_parentSelection = m_selection; - m_selection = og; - } - Update(); -} - -void V4StudioFrame::OnNewLayer2D(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *top = m_pV4sm->GetRootNode(); - if (!top) { - top = m_pV4sm->SetTopNode(TAG_MPEG4_Layer2D); - m_selection = top; - m_parentSelection = NULL; - } else { - GF_Node *l2d = m_pV4sm->NewNode(TAG_MPEG4_Layer2D); - gf_node_insert_child(m_selection, l2d, -1); - gf_node_register(l2d, m_selection); - m_parentSelection = m_selection; - m_selection = l2d; - } - Update(); -} - -void V4StudioFrame::OnNewText(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *text = m_pV4sm->NewNode(TAG_MPEG4_Text); - M_Shape *shape = (M_Shape *)m_selection; - shape->geometry = text; - gf_node_register(text, m_selection); - m_parentSelection = m_selection; - m_selection = text; - Update(); -} - -void V4StudioFrame::OnNewFontStyle(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *fs = m_pV4sm->NewNode(TAG_MPEG4_FontStyle); - M_Text *text = (M_Text *)m_selection; - text->fontStyle = fs; - gf_node_register(fs, m_selection); - m_selection = fs; - m_parentSelection = (GF_Node *)text; - Update(); -} - -void V4StudioFrame::OnNewRect(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *rect = m_pV4sm->NewNode(TAG_MPEG4_Rectangle); - M_Shape *shape = (M_Shape *)m_selection; - shape->geometry = rect; - gf_node_register(rect, m_selection); - m_parentSelection = m_selection; - m_selection = rect; - Update(); -} - -void V4StudioFrame::OnNewCircle(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *circle = m_pV4sm->NewNode(TAG_MPEG4_Circle); - M_Shape *shape = (M_Shape *)m_selection; - shape->geometry = circle; - gf_node_register(circle, m_selection); - ((M_Circle *) circle)->radius = 75; - m_parentSelection = m_selection; - m_selection = circle; - Update(); -} - -void V4StudioFrame::OnNewTransform2D(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *t2d = m_pV4sm->NewNode(TAG_MPEG4_Transform2D); - if (!m_selection) m_selection = m_pV4sm->GetRootNode(); - gf_node_insert_child(m_selection, t2d, -1); - gf_node_register(t2d, m_selection); - m_parentSelection = m_selection; - m_selection = t2d; - Update(); -} - -void V4StudioFrame::OnNewColorTransform(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *ct = m_pV4sm->NewNode(TAG_MPEG4_ColorTransform); - if (!m_selection) m_selection = m_pV4sm->GetRootNode(); - gf_node_insert_child(m_selection, ct, -1); - gf_node_register(ct, m_selection); - m_parentSelection = m_selection; - m_selection = ct; - Update(); -} - -void V4StudioFrame::OnNewTransformMatrix2D(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *tm2d = m_pV4sm->NewNode(TAG_MPEG4_TransformMatrix2D); - if (!m_selection) m_selection = m_pV4sm->GetRootNode(); - gf_node_insert_child(m_selection, tm2d, -1); - gf_node_register(tm2d, m_selection); - m_parentSelection = m_selection; - m_selection = (GF_Node *)tm2d; - Update(); -} - -void V4StudioFrame::OnNewShape(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *shape = m_pV4sm->NewNode(TAG_MPEG4_Shape); - gf_node_insert_child(m_selection, shape, -1); - gf_node_register( shape, m_selection); - m_parentSelection = m_selection; - m_selection = (GF_Node *)shape; - Update(); -} - -void V4StudioFrame::OnNewAppearance(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *app = m_pV4sm->NewNode(TAG_MPEG4_Appearance); - M_Shape *shape = (M_Shape *)m_selection; - shape->appearance = app; - gf_node_register(app, m_selection); - m_parentSelection = m_selection; - m_selection = app; - Update(); -} - -void V4StudioFrame::OnNewLinearGradient(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *lg = m_pV4sm->NewNode(TAG_MPEG4_LinearGradient); - M_Appearance *app = (M_Appearance *)m_selection; - app->texture = lg; - gf_node_register(lg, m_selection); - m_parentSelection = m_selection; - m_selection = (GF_Node *)lg; - Update(); -} - -void V4StudioFrame::OnNewRadialGradient(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *rg = m_pV4sm->NewNode(TAG_MPEG4_RadialGradient); - M_Appearance *app = (M_Appearance *)m_selection; - app->texture = rg; - gf_node_register(rg, m_selection); - m_parentSelection = m_selection; - m_selection = rg; - Update(); -} - - -void V4StudioFrame::OnNewMaterial2D(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *mat2d = m_pV4sm->NewNode(TAG_MPEG4_Material2D); - M_Appearance *app = (M_Appearance *)m_selection; - app->material = mat2d; - gf_node_register(mat2d, m_selection); - m_parentSelection = m_selection; - - m_selection = mat2d; - Update(); -} - -void V4StudioFrame::OnNewLineProps(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *lp = m_pV4sm->NewNode(TAG_MPEG4_LineProperties); - M_Material2D *mat2d= (M_Material2D *)m_selection; - mat2d->lineProps = lp; - gf_node_register(lp, m_selection); - m_parentSelection = m_selection; - m_selection = lp; - Update(); -} - -void V4StudioFrame::OnNewXLineProps(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *lp = m_pV4sm->NewNode(TAG_MPEG4_XLineProperties); - M_Material2D *mat2d= (M_Material2D *)m_selection; - mat2d->lineProps = lp; - gf_node_register(lp, m_selection); - m_parentSelection = m_selection; - m_selection = lp; - Update(); -} - -void V4StudioFrame::OnNewSound(wxCommandEvent &event) -{ -} - -void V4StudioFrame::OnNewBackground2D(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *b2d = m_pV4sm->NewNode(TAG_MPEG4_Background2D); - gf_node_insert_child(m_selection, b2d, -1); - gf_node_register(b2d, m_selection); - m_parentSelection = m_selection; - m_selection = b2d; - Update(); -} - -void V4StudioFrame::OnNewImageTexture(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *it = m_pV4sm->NewNode(TAG_MPEG4_ImageTexture); - M_Appearance *app = (M_Appearance *) m_selection; - app->texture = it; - gf_node_register(it, m_selection); - m_parentSelection = m_selection; - m_selection = it; - Update(); -} - -void V4StudioFrame::OnNewMovieTexture(wxCommandEvent &event) -{ - if (!m_pV4sm) return; - GF_Node *mt = m_pV4sm->NewNode(TAG_MPEG4_MovieTexture); - M_Appearance *app = (M_Appearance *)m_selection; - app->texture = mt; - gf_node_register(mt, m_selection); - m_parentSelection = m_selection; - m_selection = mt; - Update(); -} - -void V4StudioFrame::UpdateSelection(GF_Node *node, GF_Node *parent) -{ - SetSelection(node); - SetParentSelection(parent); - m_pMainToolbar->EnableTool(TOOL_EDIT_CUT, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_COPY, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_DELETE, true); - UpdateToolBar(); - fieldView->SetNode(node); - fieldView->Create(); -} - - -// Update display -void V4StudioFrame::Update() -{ - if (m_pV4sm){ - if (m_pV4sm->GetGPACPanel()) m_pV4sm->GetGPACPanel()->Update(); - treeView->Refresh(m_pV4sm->GetRootNode()); - } else { - treeView->Refresh(NULL); - } - UpdateToolBar(); -} - -void V4StudioFrame::UpdateToolBar() -{ - bool enableGeometry = false, - enableAppearance = false, - enableMaterial = false, - enableGroupNode = false, - enableLineProps = false, - enableFontStyle = false, - enable2DNode = false, - enableTexture = false, - enableTopNode = false, - enableBackground = false; - - // a scene must have been created to enable the controls - if (m_pV4sm && m_pV4sm->GetInlineScene()) { - if (m_selection != NULL) { - u32 tag = gf_node_get_tag(m_selection); - GF_Node * node = m_selection; - enableBackground = true; - switch (tag) { - case TAG_MPEG4_Switch: - case TAG_MPEG4_OrderedGroup: - case TAG_MPEG4_Layer2D: - case TAG_MPEG4_Transform2D: - case TAG_MPEG4_TransformMatrix2D: - case TAG_MPEG4_ColorTransform: - enableGroupNode = true; - enable2DNode = true; - break; - case TAG_MPEG4_Shape: - if (!((M_Shape *)node)->geometry) enableGeometry = true; - if (!((M_Shape *)node)->appearance) enableAppearance = true; - break; - case TAG_MPEG4_Appearance: - if (!((M_Appearance *)node)->material) enableMaterial = true; - if (!((M_Appearance *)node)->texture) enableTexture = true; - break; - case TAG_MPEG4_Material2D: - if (!((M_Material2D *)node)->lineProps) enableLineProps = true; - break; - case TAG_MPEG4_Text: - if (!((M_Text *)node)->fontStyle) enableFontStyle = true; - break; - case TAG_MPEG4_Rectangle: - case TAG_MPEG4_Circle: - case TAG_MPEG4_ImageTexture: - case TAG_MPEG4_MovieTexture: - case TAG_MPEG4_Background2D: - break; - } - } else { - enableTopNode = true; - } - } - - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_ORDEREDGROUP, enableGroupNode || enable2DNode || enableTopNode); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_LAYER2D, enableGroupNode || enable2DNode || enableTopNode); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_TRANSFORM2D, enableGroupNode || enable2DNode); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_COLOR_TRANSFORM, enableGroupNode || enable2DNode); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_TRANSFORMMATRIX2D, enableGroupNode || enable2DNode); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_SHAPE, enable2DNode); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_RECT, enableGeometry); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_CIRCLE, enableGeometry); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_IFS2D, enableGeometry); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_ILS2D, enableGeometry); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_TEXT, enableGeometry); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_MOVIE, enableTexture); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_IMAGE, enableTexture); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_SOUND, enable2DNode); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_APPEARANCE, enableAppearance); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_MATERIAL2D, enableMaterial); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_LINEAR_GRADIENT, enableTexture); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_RADIAL_GRADIENT, enableTexture); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_LINEPROPS, enableLineProps); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_XLINEPROPS, enableLineProps); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_FONTSTYLE, enableFontStyle); - m_pLowLevelNodeToolbar->EnableTool(TOOL_NEW_BACKGROUND2D, enableBackground); -} - -// Cut and paste functions -void V4StudioFrame::OnEditCut(wxCommandEvent &WXUNUSED(event)) -{ - if (!m_selection) return; - - m_clipboardNode = m_selection; - m_clipboardParentNode = m_parentSelection; - gf_node_remove_child(m_parentSelection, m_selection); - m_pMainToolbar->EnableTool(TOOL_EDIT_CUT, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_COPY, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE_USE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_DELETE, false); - - Update(); -} - -void V4StudioFrame::OnEditDelete(wxCommandEvent &WXUNUSED(event)) -{ - if (!m_selection) return; - - gf_node_remove_child(m_parentSelection, m_selection); - m_clipboardNode = NULL; - m_clipboardParentNode = NULL; - m_pMainToolbar->EnableTool(TOOL_EDIT_CUT, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_COPY, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE_USE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_DELETE, false); - - Update(); -} - -void V4StudioFrame::OnEditCopy(wxCommandEvent &WXUNUSED(event)) -{ - if (!m_selection) return; - - m_clipboardNode = m_selection; - m_clipboardParentNode = m_parentSelection; - m_pMainToolbar->EnableTool(TOOL_EDIT_CUT, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_COPY, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE_USE, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_DELETE, false); - - Update(); -} - -void V4StudioFrame::OnEditPaste(wxCommandEvent &WXUNUSED(event)) -{ - if (!m_pV4sm) return; - if (m_clipboardNode == NULL) return; - - GF_Node *copy = m_pV4sm->CopyNode(m_clipboardNode, m_parentSelection, true); - gf_node_insert_child(m_selection, copy, -1); - m_pMainToolbar->EnableTool(TOOL_EDIT_CUT, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_COPY, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE_USE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_DELETE, false); - - Update(); -} - -void V4StudioFrame::OnEditPasteUse(wxCommandEvent &WXUNUSED(event)) -{ - if (!m_pV4sm) return; - if (m_clipboardNode == NULL) return; - - GF_Node *copy = m_pV4sm->CopyNode(m_clipboardNode, m_parentSelection, false); - gf_node_register(copy, m_selection); - gf_node_insert_child(m_selection, copy, -1); - m_pMainToolbar->EnableTool(TOOL_EDIT_CUT, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_COPY, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE, true); - m_pMainToolbar->EnableTool(TOOL_EDIT_PASTE_USE, false); - m_pMainToolbar->EnableTool(TOOL_EDIT_DELETE, false); - - Update(); -} - -// OnAddToTimeLine -- adds a node in the timeline (meaning creating a node ID and adding it to the dictionnary and the pool) -void V4StudioFrame::OnAddToTimeLine(wxCommandEvent &event) { - if (!m_pV4sm) return; - if (!m_selection) return; // don't add nothing - - // if object has no node id then create one - if (! gf_node_get_id(m_selection) ) - m_pV4sm->CreateIDandAddToPool(m_selection); - - // Adds the node to the dictionnary -// m_pV4sm->AddToDictionnary(m_selection); - - // calls timeline function to add the line - char c[50]; - strcpy(c, gf_node_get_name(m_selection)); - timeLine->AddLine( gf_node_get_id(m_selection), wxString(c) ); -} - - -// NextFrame -- goto next frame -void V4StudioFrame::NextFrame(wxCommandEvent &event) { - //gf_term_play_from_time(gpacPanel->GetMPEG4Terminal(), 1000); - m_selection = NULL; - Update(); -} - - -// SwitchView -- switches between scene editing and dictionnary editing -void V4StudioFrame::SwitchView(wxCommandEvent &event) { - SetEditDict(!editDict); -} - - - -/****** Access Functions ******/ - -// changes time to the frame specified, implies playing the scene up to that point -void V4StudioFrame::SetFrame(unsigned long _frame) { - // TODO : - m_frame = _frame; -} - - -// SetEditDict -- edit the dictionnary or not -void V4StudioFrame::SetEditDict(bool _editDict) { - - // does nothing if no scene - if (!m_pV4sm) return; - if ( ! m_pV4sm->GetSceneGraph() ) return; - - editDict = _editDict; - - if (editDict) treeView->Refresh(m_pV4sm->GetDictionnary()); - else treeView->Refresh(m_pV4sm->GetRootNode()); -} - - -// GetEditDict -- Access to edit dict -bool V4StudioFrame::GetEditDict() const { - return editDict; -} diff --git a/applications/v4studio/V4StudioFrame.h b/applications/v4studio/V4StudioFrame.h deleted file mode 100644 index f0c79b0..0000000 --- a/applications/v4studio/V4StudioFrame.h +++ /dev/null @@ -1,211 +0,0 @@ -#ifndef V4STUDIO_FRAME_H -#define V4STUDIO_FRAME_H - -#include "safe_include.h" // include m4_tools.h - -#include -#include -#include - -// UI -#include "V4StudioTree.h" -#include "V4FieldList.h" -#include "V4TimeLine\V4TimeLine.h" -#include "V4CommandPanel.h" - -// Scene data -#include "V4SceneManager.h" - -enum { - // File Menu commands - MENU_FILE_NEW, - MENU_FILE_OPEN, - MENU_FILE_SAVE, - MENU_FILE_CLOSE, - MENU_FILE_QUIT, - - // Tools Menu commands - MENU_TOOL_SHOW_LOWLEVEL, - MENU_TOOL_SHOW_HIGHLEVEL, - - // Generic Toolbar commands - TOOL_FILE_NEW, - TOOL_FILE_OPEN, - TOOL_FILE_SAVE, - TOOL_FILE_CLOSE, - TOOL_FILE_PREVIEW, - TOOL_EDIT_CUT, - TOOL_EDIT_COPY, - TOOL_EDIT_PASTE, - TOOL_EDIT_PASTE_USE, - TOOL_EDIT_DELETE, - TOOL_EDIT_UNDO, - TOOL_EDIT_REDO, - TOOL_FRAME_COMBO, - TOOL_ADD_TO_TL, - TOOL_NEXT_FRAME, - TOOL_VIEW_DICT, - - CHANGE_SIZE_DIALOG, - CHANGE_FRAMERATE, - CHANGE_LENGTH, - - /* High level node creation */ - TOOL_NEW_2DSCENE, - - /* Low level node creations */ - // 2D node Toolbar commands - TOOL_NEW_ORDEREDGROUP, - TOOL_NEW_LAYER2D, - TOOL_NEW_TRANSFORM2D, - TOOL_NEW_TRANSFORMMATRIX2D, - TOOL_NEW_COLOR_TRANSFORM, - TOOL_NEW_SHAPE, - - // Appearance and sub-appearance Toolbar commands - TOOL_NEW_APPEARANCE, - TOOL_NEW_MATERIAL2D, - TOOL_NEW_LINEPROPS, - TOOL_NEW_XLINEPROPS, - TOOL_NEW_FONTSTYLE, - TOOL_NEW_LINEAR_GRADIENT, - TOOL_NEW_RADIAL_GRADIENT, - - // Geometry Toolbar commands - TOOL_NEW_RECT, - TOOL_NEW_CIRCLE, - TOOL_NEW_IFS2D, - TOOL_NEW_ILS2D, - TOOL_NEW_TEXT, - - // Media Toolbar commands - TOOL_NEW_BACKGROUND2D, - TOOL_NEW_MOVIE, - TOOL_NEW_IMAGE, - TOOL_NEW_SOUND -}; - -class V4StudioFrame: public wxFrame { -public: - - // Constructor / Desctructor - V4StudioFrame(); - ~V4StudioFrame(); - - /* generic UI functions */ - - /* File Menu functions */ - void OnNew(wxCommandEvent &event); - void OnFileOpen(wxCommandEvent &event); - void OnSave(wxCommandEvent &event); - void OnClose(wxCommandEvent &event); - void OnQuit(wxCommandEvent &event); - void OnChangeSize(wxCommandEvent &event); - void OnChangeFrameRate(wxCommandEvent &event); - void OnChangeLength(wxCommandEvent &event); - - /* Tools Menu functions */ - void OnLowLevelTools(wxCommandEvent &event); - void OnHighLevelTools(wxCommandEvent &event); - - /* edition toolbar functions */ - void OnEditCut(wxCommandEvent &event); - void OnEditCopy(wxCommandEvent &event); - void OnEditPaste(wxCommandEvent &event); - void OnEditPasteUse(wxCommandEvent &event); - void OnEditDelete(wxCommandEvent &event); - void OnAddToTimeLine(wxCommandEvent &event); - void OnCombo(wxCommandEvent& event); - void NextFrame(wxCommandEvent &event); - void SwitchView(wxCommandEvent &event); - - /* new components toolbar functions */ - void OnNewLayer2D(wxCommandEvent &event); - void OnNewOrderedGroup(wxCommandEvent &event); - void OnNewTransform2D(wxCommandEvent &event); - void OnNewTransformMatrix2D(wxCommandEvent &event); - void OnNewColorTransform(wxCommandEvent &event); - void OnNewShape(wxCommandEvent &event); - void OnNewAppearance(wxCommandEvent &event); - void OnNewMaterial2D(wxCommandEvent &event); - void OnNewLinearGradient(wxCommandEvent &event); - void OnNewRadialGradient(wxCommandEvent &event); - void OnNewLineProps(wxCommandEvent &event); - void OnNewXLineProps(wxCommandEvent &event); - void OnNewText(wxCommandEvent &event); - void OnNewFontStyle(wxCommandEvent &event); - void OnNewRect(wxCommandEvent &event); - void OnNewCircle(wxCommandEvent &event); - void OnNewSound(wxCommandEvent &event); - void OnNewBackground2D(wxCommandEvent &event); - void OnNewImageTexture(wxCommandEvent &event); - void OnNewMovieTexture(wxCommandEvent &event); - - - /* display update functions */ - void Update(); - void UpdateSelection(GF_Node *node, GF_Node *parent); - void SetSelection(GF_Node *node) { m_selection = node; } - void SetParentSelection(GF_Node *node) { m_parentSelection = node; } - void UpdateToolBar(); - void SceneGraphChanged(); - - - /* access to private members */ - - // UI objects - V4FieldList * GetFieldView() { return fieldView; } - V4StudioTree * GetTreeView() { return treeView; } - V4CommandPanel * GetCmdPanel() { return cmdPanel; } - V4TimeLine * GetTimeLine() { return timeLine; } - V4SceneManager * GetV4SceneManager() { return m_pV4sm; } - - // variables - void SetFrame(unsigned long _frame); // changes time to the frame specified, implies playing the scene up to that point - void SetEditDict(bool editDict); // edit the dictionnary or not - bool GetEditDict() const; - - -private: - void set_properties(); - void do_layout(); - -protected: - - DECLARE_EVENT_TABLE() - - // select, cut and paste members - GF_Node *m_selection; - GF_Node *m_parentSelection; - GF_Node *m_clipboardNode; - GF_Node *m_clipboardParentNode; - - // scene data - V4SceneManager *m_pV4sm; - - // UI objects - V4StudioTree *treeView; - V4FieldList *fieldView; - V4TimeLine *timeLine; - V4CommandPanel *cmdPanel; - - wxMenu *m_pFileMenu; - wxMenu *m_pToolsMenu; - wxStatusBar *m_pStatusbar; - // The Main bar that contains the new, load, save, cut, copy ... - wxToolBar *m_pMainToolbar; - - // The tool bar to create all the MPEG-4 nodes - wxToolBar *m_pLowLevelNodeToolbar; - wxToolBar *m_pHighLevelNodeToolbar; - u32 m_uSelectedNodeToolBar; - - // editing states machine - bool editDict; // true if we are editing the dictionnary - unsigned long m_frame; // frame currently selected - -}; - - -#endif - diff --git a/applications/v4studio/V4StudioTree.cpp b/applications/v4studio/V4StudioTree.cpp deleted file mode 100644 index 4e06364..0000000 --- a/applications/v4studio/V4StudioTree.cpp +++ /dev/null @@ -1,386 +0,0 @@ -#include "safe_include.h" - -// For compilers that supports precompilation , includes "wx/wx.h" -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include "V4StudioTree.h" -#include "V4StudioFrame.h" - -#include "V4SceneManager.h" // DICTNAME constant - -#include "wx/image.h" -#include "wx/imaglist.h" -#include "wx/treectrl.h" - -#include - -#include "treeIcon1.xpm" -#include "treeIcon2.xpm" -#include "treeIcon3.xpm" -#include "treeIcon4.xpm" -#include "treeIcon5.xpm" - -#include - - -BEGIN_EVENT_TABLE(V4StudioTree, wxTreeCtrl) - EVT_TREE_SEL_CHANGED(-1, V4StudioTree::OnSelChanged) - EVT_TREE_ITEM_RIGHT_CLICK(-1, V4StudioTree::OnItemRightClick) - EVT_TREE_BEGIN_DRAG(-1, V4StudioTree::OnBeginDrag) - EVT_TREE_END_DRAG(-1, V4StudioTree::OnEndDrag) -END_EVENT_TABLE() - -GF_Err V4StudioTreeItemData::GetField(GF_FieldInfo *f) -{ - if (!f || fieldIndex < 0) return GF_BAD_PARAM; - return gf_node_get_field(parent, fieldIndex, f); -} - -V4StudioTree::V4StudioTree(wxWindow *parent_, wxSize size,V4FieldList *fieldView) : - wxTreeCtrl(parent_, -1, wxDefaultPosition, size, wxTR_DEFAULT_STYLE) -{ - CreateImageList(); - AddRoot("Scene", V4StudioTree::TreeCtrlIcon_Folder, V4StudioTree::TreeCtrlIcon_FolderOpened); - m_transformNode = NULL; - m_selectedNode = NULL; - - parent = (V4StudioFrame *) parent_; -} - - -// Refresh -- redraws the tree starting at the specified node -void V4StudioTree::Refresh(GF_Node * node) -{ - - // check if we have to display the dictionnary or not - if (parent->GetEditDict()) - node = parent->GetV4SceneManager()->GetDictionnary(); - - - wxTreeItemId rootId = GetRootItem(); - CollapseAndReset(rootId); - if (node) { - AddNodesToItem(rootId, node, -1, -1); - Expand(rootId); - } -} - -void V4StudioTree::AddNodesToItem(wxTreeItemId parentItemId, GF_Node * node, s32 fieldIndex, s32 position) -{ - GF_FieldInfo field; - u32 count, i, j; - char *name; - - if (!node) return; - - // displays the name and the defname it exists - u32 s = strlen(gf_node_get_class_name(node)); - - if (gf_node_get_name(node)) { - s += strlen(gf_node_get_name(node)); - name = new char[s+4]; - strcpy(name, gf_node_get_class_name(node)); - strcat(name, " - "); - strcat(name, gf_node_get_name(node)); - } else { - name = new char[s+1]; - strcpy(name, gf_node_get_class_name(node)); - } - - GF_Node * parent = NULL; - - V4StudioTreeItemData *parentItemData = (V4StudioTreeItemData *)GetItemData(parentItemId); - if (parentItemData != NULL) parent = parentItemData->GetNode(); - - V4StudioTreeItemData * currentItemData = new V4StudioTreeItemData(node, parent, fieldIndex, position); - wxTreeItemId nodeItemId; - if (position == -1) nodeItemId = AppendItem(parentItemId, wxString(name), -1, -1, currentItemData); - else nodeItemId = InsertItem(parentItemId, position, wxString(name), -1, -1, currentItemData); - - delete [] name; - name = NULL; - - count = gf_node_get_field_count(node); - for (i=0;iAdd(icons[i]); - else images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); - } - AssignImageList(images); -} - -void V4StudioTree::OnSelChanged(wxTreeEvent& event) -{ - wxKeyEvent kevt = event.GetKeyEvent(); - - wxTreeItemId itemId = event.GetItem(); - m_selectedItem = itemId; - if (itemId.IsOk()) { - V4StudioTreeItemData *itemData = (V4StudioTreeItemData *)GetItemData(itemId); - if (!itemData) { - event.Skip(); - return; - } - GF_Node *itemNode = itemData->GetNode(); - GF_Node *itemParentNode = itemData->GetNodeParent(); - if (!itemNode) { - event.Skip(); - return; - } - V4StudioFrame *mainFrame = (V4StudioFrame *)GetParent(); - mainFrame->UpdateSelection(itemNode, itemParentNode); - } -} - -void V4StudioTree::SetSelectedItem(GF_Node *node) -{ - if (m_selectedNode == node) return; - wxTreeItemId rootId = GetRootItem(); - wxTreeItemId itemId = FindNodeItem(rootId, node); - m_transformNode = FindTransformNode(itemId); - itemId = GetItemParent(itemId); - if (itemId.IsOk()) { - V4StudioTreeItemData *data = (V4StudioTreeItemData *)GetItemData(itemId); - if (data != NULL) { - V4StudioFrame *mainFrame = (V4StudioFrame *)GetParent(); - GF_Node *itemNode = data->GetNode(); - m_selectedNode = itemNode; - GF_Node *itemParentNode = data->GetNodeParent(); - mainFrame->UpdateSelection(itemNode, itemParentNode); - } - SelectItem(itemId); - } -} - -wxTreeItemId V4StudioTree::FindNodeItem(wxTreeItemId itemId, GF_Node *node) -{ - void* cookie; - V4StudioTreeItemData *data = (V4StudioTreeItemData *)GetItemData(itemId); - if (data != NULL) { - if (data->GetNode() == node) return itemId; - } - wxTreeItemId ret = (wxTreeItemId)0l; - wxTreeItemId child = GetFirstChild(itemId, cookie); - while (child.IsOk()) { - wxTreeItemId ret = FindNodeItem(child, node); - if (ret.IsOk()) return ret; - child = GetNextChild(itemId, cookie); - } - return ret; -} - -void V4StudioTree::OnItemRightClick(wxTreeEvent &event) -{ - wxTreeItemId itemId = event.GetItem(); -} - -void V4StudioTree::OnBeginDrag(wxTreeEvent& event) -{ - // need to explicitly allow drag - if ( event.GetItem() != GetRootItem() ){ - m_draggedItem = event.GetItem(); - V4StudioTreeItemData *draggedData = (V4StudioTreeItemData *)GetItemData(m_draggedItem); - event.Allow(); - } else { - wxLogMessage(wxT("OnBeginDrag: this item can't be dragged.")); - } -} - -void V4StudioTree::OnEndDrag(wxTreeEvent& event) -{ - wxTreeItemId itemSrc = m_draggedItem, itemDst = event.GetItem(), dstParentItem = GetItemParent(itemDst); - m_draggedItem = (wxTreeItemId)0l; - - V4StudioTreeItemData *srcData = (V4StudioTreeItemData *)GetItemData(itemSrc); - GF_FieldInfo srcField; - srcData->GetField(&srcField); - // Removal of the src item from its parent field - switch (srcField.fieldType) { - case GF_SG_VRML_SFNODE: - if (* (GF_Node **) srcField.far_ptr) {} - break; - case GF_SG_VRML_MFNODE: - { - GF_ChildNodeItem *nodes = (* (GF_ChildNodeItem **) srcField.far_ptr); - gf_node_list_del_child_idx(&nodes, srcData->GetPosition()); - } - break; - default: - break; - } - - GF_Node *srcNode = srcData->GetNode(); - GF_FieldInfo dstField; - V4StudioTreeItemData *dstData = (V4StudioTreeItemData *)GetItemData(itemDst); - dstData->GetField(&dstField); - // Addition of the src item prior to the dest item - switch (dstField.fieldType) { - case GF_SG_VRML_SFNODE: - if (* (GF_Node **) dstField.far_ptr) {} - break; - case GF_SG_VRML_MFNODE: - { - GF_ChildNodeItem *nodes = (* (GF_ChildNodeItem **) dstField.far_ptr); - gf_node_list_insert_child(&nodes, srcNode, dstData->GetPosition()); - gf_node_dirty_set(dstData->GetNode(), 0, 1); - } - break; - default: - break; - } - - GF_Node *dstParentNode = dstData->GetNodeParent(); - - Delete(itemSrc); - AddNodesToItem(dstParentItem, srcNode, dstData->GetFieldIndex(), dstData->GetPosition()); - V4StudioFrame *mainFrame = (V4StudioFrame *)GetParent(); - mainFrame->UpdateSelection(srcNode,dstData->GetNodeParent()); - mainFrame->Update(); -} - -GF_Node *V4StudioTree::FindTransformNode(wxTreeItemId itemId) -{ - GF_Node *transformNode = NULL; - while (true) { - if (itemId.IsOk()) { - V4StudioTreeItemData *data = (V4StudioTreeItemData *)GetItemData(itemId); - if (data != NULL) { - GF_Node *itemNode = data->GetNode(); - u32 tag = gf_node_get_tag(itemNode); - if (tag == TAG_MPEG4_Transform2D || tag == TAG_MPEG4_TransformMatrix2D) { - transformNode = itemNode; - break; - } - } else { - break; - } - } else { - break; - } - itemId = GetItemParent(itemId); - } - return transformNode; -} - -void V4StudioTree::Translate(int dX, int dY) -{ - if (m_transformNode) { - GF_FieldInfo field; - u32 tag = gf_node_get_tag(m_transformNode); - if (tag == TAG_MPEG4_Transform2D){ - gf_node_get_field(m_transformNode, 7, &field); - ((SFVec2f *)field.far_ptr)->x += dX; - ((SFVec2f *)field.far_ptr)->y += dY; - } else { - gf_node_get_field(m_transformNode, 5, &field); - *((SFFloat *)field.far_ptr) += dX; - gf_node_get_field(m_transformNode, 8, &field); - *((SFFloat *)field.far_ptr) += dY; - } - V4StudioFrame *mainFrame = (V4StudioFrame *)GetParent(); - mainFrame->GetFieldView()->SetNode(m_transformNode); - mainFrame->GetFieldView()->Create(); - } -} - -void V4StudioTree::Scale(int dX, int dY) -{ - if (m_transformNode && (dX || dY)) { - GF_FieldInfo field; - u32 tag = gf_node_get_tag(m_transformNode); - if (tag == TAG_MPEG4_Transform2D){ - gf_node_get_field(m_transformNode, 5, &field); - if (dX) ((SFVec2f *)field.far_ptr)->x *= (dX>0?1.01:0.99); - if (dY) ((SFVec2f *)field.far_ptr)->y *= (dY>0?1.01:0.99); - } else { - gf_node_get_field(m_transformNode, 3, &field); - if (dX) *((SFFloat *)field.far_ptr) *= (dX>0?1.01:0.99); - gf_node_get_field(m_transformNode, 7, &field); - if (dY) *((SFFloat *)field.far_ptr) *= (dY>0?1.01:0.99); - } - V4StudioFrame *mainFrame = (V4StudioFrame *)GetParent(); - mainFrame->GetFieldView()->SetNode(m_transformNode); - mainFrame->GetFieldView()->Create(); - } -} - - -void V4StudioTree::Rotate(int dX, int dY) -{ - /*quick and dirty of course...*/ - dY *= -1; - if (m_transformNode && (dX || dY)) { - u32 tag = gf_node_get_tag(m_transformNode); - if (tag == TAG_MPEG4_Transform2D){ - Double ang; - ang = atan2(dY, dX) / 100; - ((M_Transform2D *) m_transformNode)->rotationAngle += ang; - } else { - ((M_TransformMatrix2D *) m_transformNode)->mxy += dX; - ((M_TransformMatrix2D *) m_transformNode)->myx += dY; - } - V4StudioFrame *mainFrame = (V4StudioFrame *)GetParent(); - mainFrame->GetFieldView()->SetNode(m_transformNode); - mainFrame->GetFieldView()->Create(); - } -} - - diff --git a/applications/v4studio/V4StudioTree.h b/applications/v4studio/V4StudioTree.h deleted file mode 100644 index 845af74..0000000 --- a/applications/v4studio/V4StudioTree.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef _V4STUDIO_TREE_H -#define _V4STUDIO_TREE_H - -#include "safe_include.h" -#include -#include "V4FieldList.h" - -#include - - -class V4StudioFrame; - - -class V4StudioTreeItemData : public wxTreeItemData { -public: - V4StudioTreeItemData(GF_Node *n, GF_Node *p, s32 fi, s32 pos = -1) : node(n), parent(p), fieldIndex(fi), position(pos) {} - -public: - GF_Node *GetNode() { return node; } - void SetNode(GF_Node *n) { node = n; } - GF_Err GetField(GF_FieldInfo *f); - - GF_Node *GetNodeParent() { return parent; } - void SetNodeParent(GF_Node *n) { parent = n; } - s32 GetPosition() { return position; } - void SetPosition(s32 pos) { position = pos; } - void SetFieldIndex(s32 i) { fieldIndex = i; } - s32 GetFieldIndex() { return fieldIndex; } - -private: - GF_Node *node; - GF_Node *parent; - s32 fieldIndex; - s32 position; - -}; - -class V4StudioTree: public wxTreeCtrl { - -public: - enum - { - TreeCtrlIcon_File, - TreeCtrlIcon_FileSelected, - TreeCtrlIcon_Folder, - TreeCtrlIcon_FolderSelected, - TreeCtrlIcon_FolderOpened - }; - - V4StudioTree(wxWindow *parent, wxSize size, V4FieldList *fieldView); - - void CreateImageList(int size = 16); - - void Refresh(GF_Node * node); - - void OnSelChanged(wxTreeEvent& event); - void OnItemRightClick(wxTreeEvent &event); - void ShowMenu(wxTreeItemId id, const wxPoint& pt); - void OnBeginDrag(wxTreeEvent& event); - void OnEndDrag(wxTreeEvent& event); - - void SetSelectedItem(GF_Node *node); - void Translate(int dX, int dY); - void Scale(int dX, int dY); - void Rotate(int dX, int dY); - wxTreeItemId FindNodeItem(wxTreeItemId itemId, GF_Node *node); - GF_Node *FindTransformNode(wxTreeItemId itemId); - -protected: - DECLARE_EVENT_TABLE() - -private: - void AddNodesToItem(wxTreeItemId parentItemId, GF_Node * node, s32 fieldIndex, s32 position); - - wxTreeItemId m_selectedItem; // item being dragged right now - wxTreeItemId m_draggedItem; // item being dragged right now - - GF_Node * m_selectedNode; - GF_Node * m_transformNode; - - // All the component of the V4Studio Main Frame have a pointer to that Main Frame, called parent. - V4StudioFrame * parent; - -}; - -#endif diff --git a/applications/v4studio/V4TimeLine/V4TimeLine.cpp b/applications/v4studio/V4TimeLine/V4TimeLine.cpp deleted file mode 100644 index ac5acbe..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLine.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - V4TimeLine.cpp - - Implémentation de la classe V4TimeLine -*/ - -#include "V4TimeLine.h" -#include "V4TimeLineCase.h" -#include "..\V4StudioFrame.h" - - -// Constructeur -V4TimeLine::V4TimeLine(wxWindow * parent_, unsigned int timeLineLength) : wxScrolledWindow(parent_), sizer(NULL) { - - // position en X de la grille - Offset = 100; - Length = timeLineLength; - clicked = NULL; - - parent = (V4StudioFrame *) parent_; - - sizer = new wxBoxSizer(wxVERTICAL); - - // indispensable pour avoir des barres de défilement - SetScrollRate( 5, 5 ); - - hdr = new V4TimeLineHdr(this); - sizer->Add(hdr); - - SetSizer(sizer); - FitInside(); -} - - -// Destructeur -V4TimeLine::~V4TimeLine() { -} - - -// retourne la position en X du debut de la grille -int V4TimeLine::GetOffset() { - return Offset; -} - - -// returns Length attribute -unsigned int V4TimeLine::GetLength() { - return Length; -} - - -// Adds a line to the timeline -void V4TimeLine::AddLine(u32 NodeID, wxString eltName) { - // verifies that we have no line with the same NodeID - - for (int i = 0; i < lines.size(); i++) { - if (lines.at(i)->GetNodeID() == NodeID) - return; - } - - // adds the line at the end of the list, in the next position - // note that we already have the hearder line in position 0 - lines.push_back( - new V4TimeLineElt(this, lines.size()+1, NodeID, eltName, hdr->GetFrame()) - ); - - // redraws the component - sizer->Add(lines.back()); - Layout(); -} - - -// called when time changed, update display (background colors) -void V4TimeLine::SetFrame(u32 _frame, V4TimeLineCell * newClicked) { - - // updates lines display - if (_frame != hdr->GetFrame()) { - hdr->SetFrame(_frame); - - // TODO : apply all commands from previous frames. - // maybe by adding a NextFrame() method - - for (int i = 0; i < lines.size(); i++) - lines.at(i)->SetFrame(_frame); - } - - - // updates clicked state on clicked cells - - // removes state from old - if (clicked != NULL) { - u32 state = clicked->GetState(); - state &= ~CELL_STATE_CLICKED; - clicked->SetState(state); - } - - clicked = newClicked; - - // adds state to new - if (clicked != NULL) { - u32 state = clicked->GetState(); - state |= CELL_STATE_CLICKED; - clicked->SetState(state); - } - - - // updates command panel - ((V4StudioFrame *) GetParent())->GetCmdPanel()->Refresh(_frame); - -} - - -// GetSelectedID -- returns the ID of the node whose timeline is selected -u32 V4TimeLine::GetSelectedID() const { - - // if nothing is selected then returns null nodeID - if (!clicked) return 0; - - // gets the line from the cell - u32 pos = clicked->GetParent()->GetPos(); - - // gets the node id (!! the header line is first) - if (pos) return lines.at(pos-1)->GetNodeID(); - else return 0; // if we clicked on a header cell -} - - -// AddCommand -- -void V4TimeLine::AddCommand(GF_Command * c) { - clicked->AddCommand(c); -} - - -// DeleteCommand -- -void V4TimeLine::DeleteCommand(u32 n) { - clicked->DeleteCommand(n); -} - - -// GetCommand -- -GF_Command * V4TimeLine::GetCommand(u32 n) { - return clicked->GetCommand(n); -} - - -// SetLength -- -void V4TimeLine::SetLength(const unsigned int length_) { - hdr->SetLength(length_); - - // if the selected frames will be deleted, we select the last cell - if (hdr->GetFrame() > length_) SetFrame(length_); - - for (int i = 0; i < lines.size(); i++) - lines.at(i)->SetLength(length_); - - Length = length_; - - FitInside(); -} \ No newline at end of file diff --git a/applications/v4studio/V4TimeLine/V4TimeLine.h b/applications/v4studio/V4TimeLine/V4TimeLine.h deleted file mode 100644 index 98908a8..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLine.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - V4TimeLine.h - - V4Studio component allowing to edit timings - The component draw sub components whose type is V4TimeLineElt -*/ - -#ifndef _V4TimeLine_ -#define _V4TimeLine_ - -#include "../safe_include.h" - -// wxWidgets includes -#include -#include - -// Own includes -#include "V4TimeLineElt.h" -#include "V4TimeLineHdr.h" - -// STL includes -#include - -class V4TimeLineCell; -class V4StudioFrame; - - - -class V4TimeLine : public wxScrolledWindow { - public: - // Constructeur -- timeLineLength est compté en images - V4TimeLine(wxWindow * parent, unsigned int timeLineLength = 50); - - // Desctructeur - ~V4TimeLine(); - - void AddLine(u32 NodeID, wxString eltName); // Adds a line to the timeline - // TODO : add an additionnal parameter to specify a pointer to the element represented by the line - // TODO : use node pointer instead of id ? - - void Clear(); // clears all the line in the timeline - // TODO : check if everything is destroyed correctly - - // retourne la position en X du debut de la grille - int GetOffset(); - - // access to Length - unsigned int GetLength(); - void SetLength(const unsigned int length_); - - // called when time changed, update display (background colors) - void SetFrame(u32 _frame, V4TimeLineCell * newClicked = NULL); - - // returns the ID of the node whose timeline is selected - u32 GetSelectedID() const; - - // Deletes a command from the current cell - void DeleteCommand(u32 n); - - // Adds a command to the current cell - void AddCommand(GF_Command *); - - // Retrieves the list of commands for the current cell - GF_Command * GetCommand(u32 n); - - // pointer to the parent - V4StudioFrame * parent; - - - private: - // composants graphiques - std::vector lines; - V4TimeLineHdr * hdr; - wxBoxSizer * sizer; - - // attributs divers - int Offset; // X position of the grid - u32 Length; // length (in frames) of the scene - V4TimeLineCell * clicked; // cell currently "clicked" - - -}; - -#endif \ No newline at end of file diff --git a/applications/v4studio/V4TimeLine/V4TimeLineCase.cpp b/applications/v4studio/V4TimeLine/V4TimeLineCase.cpp deleted file mode 100644 index 375e97d..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLineCase.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - V4TimeLineCase.cpp - -*/ - -#include "V4TimeLineCase.h" -#include "V4TimeLineLine.h" -#include "V4TimeLine.h" - -#include "..\V4StudioFrame.h" -#include "..\V4SceneManager.h" - - -BEGIN_EVENT_TABLE(V4TimeLineCell, wxWindow) - EVT_PAINT(V4TimeLineCell::OnPaint) - EVT_LEFT_UP(V4TimeLineCell::OnLeftUp) -END_EVENT_TABLE() - - -// Constructor -V4TimeLineCell::V4TimeLineCell(V4TimeLineLine * parent_, unsigned int _num, unsigned int _type) : wxWindow(parent_, -1), num(_num), state(0), type(_type) { - - parent = parent_; - commands = gf_list_new(); - - SetSize(parent_->GetOffset() + _num * 20, 0, -1, -1); - - // line, timeline, frame - v4sf = (V4StudioFrame *) parent->GetParent()->GetParent(); - -} - - -// destructor -V4TimeLineCell::~V4TimeLineCell() { - gf_list_del(commands); -} - - -// OnPaint -void V4TimeLineCell::OnPaint(wxPaintEvent & event) { - wxPaintDC dc(this); - - dc.BeginDrawing(); - - int w, h; - GetSize(&w, &h); - - // draws the background - dc.SetPen(*wxTRANSPARENT_PEN); - - // finds a color according to the parity - unsigned char r,g,b; - if ( ((V4TimeLineLine *)GetParent())->GetPos() % 2 ) { r = 220; g = 220; b = 255; } - else { r = 200; g = 200; b = 255; }; - - // if we are selected (ie current frame) adds green - if (state & CELL_STATE_SELECTED) - g += 35; - - wxColour c(r,g,b); - - wxBrush br(c); - dc.SetBrush( br ); - - dc.DrawRectangle(0,0,w,h); - - dc.SetBrush(*wxWHITE_BRUSH); - - // draws the vertical borders - dc.SetPen(*wxLIGHT_GREY_PEN); - dc.DrawLine(0,0,0,h); - - dc.SetPen(*wxBLACK_PEN); - - // draws state specific information - if (state & CELL_STATE_CLICKED) dc.DrawCircle(w/2,h/2,10); - if (state & CELL_STATE_COMMAND) dc.DrawRectangle(2, 2, w-4, h-4); - - // draws frame number - wxString s; - if ( (type == CELL_TYPE_HDR) && (! (num % 10)) ) { - s = s.Format(wxT("%d"), num); - // centers text - int wt, ht; - dc.GetTextExtent(s, &wt, &ht); - dc.DrawText(s, (w-wt)/2, (h-ht)/2); - } - - dc.EndDrawing(); -} - - -// OnLeftUp -- tells the application that the user switched frame -void V4TimeLineCell::OnLeftUp(wxMouseEvent & event) { - - ((V4TimeLine *) GetParent()->GetParent())->SetFrame(num, this); - - V4SceneManager * sg = v4sf->GetV4SceneManager(); - - // don't trigger any more reaction if this is a cell in the first row - //if (type == CELL_TYPE_HDR) return; - - Refresh(); - v4sf->Update(); -} - - -// SetState -- Changes cell state -void V4TimeLineCell::SetState(unsigned int _state) { - state = _state; - - // if cell is clicked but not selected, can't be clicked anymore - if ( (state & CELL_STATE_CLICKED) && !(state & CELL_STATE_SELECTED) ) - state &= ~CELL_STATE_CLICKED; - - Refresh(); -} - - -// GetState -- Retrieves cells state -unsigned int V4TimeLineCell::GetState() const { - return state; -} - - -// AddCommand -- -void V4TimeLineCell::AddCommand(GF_Command *c) { - gf_list_add(commands, c); - SetState( GetState() | CELL_STATE_COMMAND ); -} - -// DeleteCommand -- Deletes ONE command -void V4TimeLineCell::DeleteCommand(const u32 n) { - // TODO : -} - - -// DeleteCommand -- destroys all the commands from this cell (for instance when shortening the scene) -// ONLY works for NORMAL cells -void V4TimeLineCell::DeleteCommands() { - - // deletes the commands from the au - - // useful objects - V4SceneManager *sm = v4sf->GetV4SceneManager(); - GF_StreamContext *ctx = sm->GetBifsStream(); - GF_AUContext * au = NULL; - GF_Node * myNode = gf_sg_find_node( sm->GetSceneGraph(), ((V4TimeLineElt *) parent)->GetNodeID() ); - - u32 myTiming = sm->GetUnits() / sm->GetFrameRate() * num; - - // first, locates the AU - for (int i = 0; i < gf_list_count(ctx->AUs); i++) { - au = (GF_AUContext *) gf_list_get(ctx->AUs, i); - if (au->timing == myTiming) { - // then the commands for this node and deletes it - for (int j = 0; j < gf_list_count(au->commands); j++) { - GF_Command * c = (GF_Command *)gf_list_get(au->commands, j); - if ( c->node == myNode ) { - gf_sg_command_del(c); - gf_list_rem(au->commands, j); - break; - } - } - } - } - - // deletes the command in our chain - gf_list_reset(commands); - - SetState( GetState() ^ CELL_STATE_COMMAND ); -} - - -// GetCommand -- allow listing of the command for this cell -GF_Command * V4TimeLineCell::GetCommand(u32 n) { - if (gf_list_count(commands) < n) return NULL; - else return (GF_Command *) gf_list_get(commands, n); -} - - -// GetParent -- returns a pointer to parent (used to retrieve line number and node ID) -V4TimeLineLine * V4TimeLineCell::GetParent() const { - return parent; -} diff --git a/applications/v4studio/V4TimeLine/V4TimeLineCase.h b/applications/v4studio/V4TimeLine/V4TimeLineCase.h deleted file mode 100644 index 159ab22..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLineCase.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - V4TimeLineCase.h - - // TODO : description -*/ - -#ifndef _V4TimeLineCell_ -#define _V4TimeLineCell_ - - -#include - -#include - - -class V4TimeLineLine; - -// differents types of a cell -- differs with the line type -#define CELL_TYPE_HDR 0 -#define CELL_TYPE_NORMAL 1 - -// different states of a cell -#define CELL_STATE_CLICKED 1 -#define CELL_STATE_SELECTED 2 -#define CELL_STATE_COMMAND 4 - -class V4StudioFrame; - -class V4TimeLineCell: public wxWindow { - - public: - // Constructor - V4TimeLineCell(V4TimeLineLine * parent, unsigned int num=0, unsigned int type=CELL_TYPE_NORMAL); - - // Destructor - virtual ~V4TimeLineCell(); - - // Changes cell state - void SetState(unsigned int _state); - unsigned int GetState() const; - - // returns a pointer to parent (used to retrieve line number and node ID) - V4TimeLineLine * GetParent() const; - - // manipulates the commands list - void AddCommand(GF_Command *); - void DeleteCommands(); - void DeleteCommand(const u32 n); - GF_Command * GetCommand(u32 n); - - private: - unsigned int state; // possible values not yet defined - unsigned int type; // type of cell - - unsigned int num; - - DECLARE_EVENT_TABLE() - - V4StudioFrame * v4sf; - V4TimeLineLine * parent; - - GF_List * commands; // actions to perform for this object (row) when entering the frame (col) - - void OnLeftUp(wxMouseEvent &); - void OnPaint(wxPaintEvent &); -}; - -#endif \ No newline at end of file diff --git a/applications/v4studio/V4TimeLine/V4TimeLineElt.cpp b/applications/v4studio/V4TimeLine/V4TimeLineElt.cpp deleted file mode 100644 index 2247c62..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLineElt.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - V4TimeLineElt.cpp - - Implements V4TimeLineElt class -*/ - -#include "V4TimeLineElt.h" -#include "V4TimeLine.h" -#include "V4TimeLineCase.h" - -#include "..\V4StudioFrame.h" -#include "..\V4SceneManager.h" // FPS constant - - -// Constructor -V4TimeLineElt::V4TimeLineElt(V4TimeLine * parent, unsigned int pos, unsigned long _NodeID, wxString eltName, unsigned long frame) : -V4TimeLineLine(parent, pos, frame), txt(NULL), lbl(NULL) { - // creates sub-controls - - NodeID = _NodeID; - - sizer = new wxBoxSizer(wxHORIZONTAL); - SetSizer(sizer); - - lbl = new wxStaticText(this, -1, eltName); - lbl->SetSize(0,0,parent->GetOffset(), 20); - - - sizer->Add(lbl, 0, wxALL, 0); - - CreateLine(CELL_TYPE_NORMAL); - - - // locates the existing commands for a node - GF_StreamContext * stream = parent->parent->GetV4SceneManager()->GetBifsStream(); - - // tries all access units - for (i=0; i < gf_list_count(stream->AUs); i++) { - GF_AUContext * au = (GF_AUContext *) gf_list_get(stream->AUs, i); - - // and all commands in each au - for (u32 j=0; j < gf_list_count(au->commands); j++) { - GF_Command * c = (GF_Command *) gf_list_get(au->commands, j); - - // and checks whether they are appled to this node - if (gf_node_get_id(c->node) == NodeID) { - // TODO : the timing unit might not be 1 ms - u32 cellNum = au->timing / 1000 * parent->parent->GetV4SceneManager()->GetFrameRate(); - cells.at(cellNum)->SetState(CELL_STATE_COMMAND); - cells.at(cellNum)->AddCommand(c); - } - } - - } - -} - - -// Destructor -V4TimeLineElt::~V4TimeLineElt() { - -} - - -// returns NodeID -u32 V4TimeLineElt::GetNodeID() { - return NodeID; -} - - -// -unsigned char V4TimeLineElt::GetType() { - return CELL_TYPE_NORMAL; -} \ No newline at end of file diff --git a/applications/v4studio/V4TimeLine/V4TimeLineElt.h b/applications/v4studio/V4TimeLine/V4TimeLineElt.h deleted file mode 100644 index a2c77af..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLineElt.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - V4TimeLineElt.h - - Class representing one line in the timeline - - A line consists in a label, giving the name of the object it represents, and an owner drawn zone where are represented the events -*/ - -#ifndef _V4TimeLineElt_ -#define _V4TimeLineElt_ - -#include "../safe_include.h" - -// wxWidgets includes -#include - -// Own includes -#include "V4TimeLineLine.h" - - -// include GPAC -//#include "../safe_include.h" // definition des types de données - - -class V4TimeLine; - - -class V4TimeLineElt : public V4TimeLineLine { - public: - // Constructor - V4TimeLineElt(V4TimeLine * parent, unsigned int pos, unsigned long NodeID, wxString eltName, unsigned long frame=0); - - // Destructor - ~V4TimeLineElt(); - - // inherited - virtual unsigned char GetType(); - - // returns NodeID - u32 GetNodeID(); - - private: - wxTextCtrl * txt; - wxStaticText * lbl; - unsigned long NodeID; -}; - -#endif \ No newline at end of file diff --git a/applications/v4studio/V4TimeLine/V4TimeLineHdr.cpp b/applications/v4studio/V4TimeLine/V4TimeLineHdr.cpp deleted file mode 100644 index 890b174..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLineHdr.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - V4TimeLineHdr.cpp - - Implements V4TimeLineHdr class. -*/ - -#include "V4TimeLineHdr.h" -#include "V4TimeLine.h" -#include - -BEGIN_EVENT_TABLE(V4TimeLineHdr, wxWindow) -END_EVENT_TABLE() - - -// Constructor -V4TimeLineHdr::V4TimeLineHdr(V4TimeLine * parent, unsigned int pos) : V4TimeLineLine(parent, pos) { - - // Creates default line - sizer = new wxBoxSizer(wxHORIZONTAL); - SetSizer(sizer); - lbl = new wxStaticText(this, -1, wxT("Object")); - lbl->SetSize(0,0,parent->GetOffset(), 20); - sizer->Add(lbl, 0, wxALL, 0); - - CreateLine(CELL_TYPE_HDR); - -} - - -// Desctructor -V4TimeLineHdr::~V4TimeLineHdr() {}; - - -// -unsigned char V4TimeLineHdr::GetType() { - return CELL_TYPE_HDR; -} \ No newline at end of file diff --git a/applications/v4studio/V4TimeLine/V4TimeLineHdr.h b/applications/v4studio/V4TimeLine/V4TimeLineHdr.h deleted file mode 100644 index 068fff5..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLineHdr.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - V4TimeLineHdr.h - - Defines the class for printing hearder information on the timeline (frame numbers...) -*/ - -#ifndef _V4TimeLineHdr_ -#define _V4TimeLineHdr_ - -#include "../safe_include.h" - -#include -#include "V4TimeLineLine.h" // parent class - -class V4TimeLine; - - -class V4TimeLineHdr : public V4TimeLineLine { - public: - // Constructor - V4TimeLineHdr(V4TimeLine * parent, unsigned int pos=0); - - // Destructor - ~V4TimeLineHdr(); - - // inherited - virtual unsigned char GetType(); - - private: - - wxStaticText * lbl; // holds the title string - - DECLARE_EVENT_TABLE(); -}; - -#endif diff --git a/applications/v4studio/V4TimeLine/V4TimeLineLine.cpp b/applications/v4studio/V4TimeLine/V4TimeLineLine.cpp deleted file mode 100644 index 2c72bef..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLineLine.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - V4TimeLineLine.cpp - - Implements V4TimeLineLine class - -*/ - -#include "V4TimeLineLine.h" -#include "V4TimeLine.h" - -// Constructor -V4TimeLineLine::V4TimeLineLine(V4TimeLine * parent, unsigned int _pos, unsigned long frame) : wxWindow((wxWindow *) parent, -1), pos(_pos) { -} - - -// retrieves X position of the grid -unsigned int V4TimeLineLine::GetOffset() const { - return ( (V4TimeLine *)GetParent() )->GetOffset(); -} - - -// returns the number of frame in the scene -unsigned int V4TimeLineLine::GetLength() const { - return ( (V4TimeLine *)GetParent() )->GetLength(); -} - - -// returns the position of the line in the timeLine -unsigned int V4TimeLineLine::GetPos() const { - return pos; -} - - -// Update diplay to match new time -void V4TimeLineLine::SetFrame(unsigned long _frame) { - std::vector::iterator iter; - - int i = 0; - - // uptades the needed cells - - for (iter = cells.begin(); iter != cells.end(); iter++) { - // newly selected cell, adds selected state - if (i == _frame) { - unsigned int state = (*iter)->GetState(); - state |= CELL_STATE_SELECTED; - (*iter)->SetState(state); - } - - // old selected cell, deletes selected state - if ( (i == frame) && (_frame != frame) ) { - unsigned int state = (*iter)->GetState(); - state &= ~CELL_STATE_SELECTED; - (*iter)->SetState(state); - } - - i++; - } - - frame = _frame; -} - - -// Retrieves frame -unsigned long V4TimeLineLine::GetFrame() const { - return frame; -} - - -// -void V4TimeLineLine::SetLength(const unsigned int length_) { - int L = GetLength(); - - V4TimeLine * line = (V4TimeLine *) GetParent(); - SetSizeHints(line->GetOffset() + 20 * length_, -1); - line->Layout(); - - if (L <= length_) { - - for (int i = L; i < length_; i++) { - cells.push_back(new V4TimeLineCell(this,i, GetType())); - sizer->Add(cells.back(), 1, wxALL, 0); - } - } else { - for (int i = L-1; i >= length_; i--) { - if (cells.back()->GetCommand(0)) cells.back()->DeleteCommands(); - delete cells.back(); - cells.pop_back(); - } - } - -} \ No newline at end of file diff --git a/applications/v4studio/V4TimeLine/V4TimeLineLine.h b/applications/v4studio/V4TimeLine/V4TimeLineLine.h deleted file mode 100644 index 07e70a2..0000000 --- a/applications/v4studio/V4TimeLine/V4TimeLineLine.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - V4TimeLineLine.h - - Defines generic behaviour for a line in the timeline - There are two child classes: V4TimeLineElt and V4TimeLineHdr - -*/ - -#ifndef _V4TimeLineLine_ -#define _V4TimeLineLine_ - -#include "../safe_include.h" - -#include -#include -#include "V4TimeLineCase.h" - - -#define LINE_TYPE_HDR 0 -#define LINE_TYPE_ELT 1 - -class V4TimeLine; - - -// macro that creates the sizer and the grid for a line -#define CreateLine(CELL_TYPE) \ - SetSizeHints(parent->GetOffset() + 20 * GetLength(), -1); \ - \ - for (u32 i=0; iAdd(cells.back(), 1, wxALL, 0); \ - } \ - SetFrame(frame); - - -class V4TimeLineLine : public wxWindow { - public: - // Constructor - V4TimeLineLine(V4TimeLine * parent, unsigned int _pos, unsigned long frame=0); - - // retrieves the X positon of the grid - unsigned int GetOffset() const; - - // returns the Y position of the line - unsigned int GetPos() const; - - // accesses the length of the grid - unsigned int GetLength() const; - void SetLength(const unsigned int length_); - - // Update display to match new time - void SetFrame(unsigned long _frame); - unsigned long GetFrame() const; - - virtual unsigned char GetType() PURE; - - - protected: - std::vector cells; // cases of the grid - wxBoxSizer * sizer; - - unsigned int pos; // Y position of the line in the grid - - unsigned long frame; // current frame - -}; - -#endif \ No newline at end of file diff --git a/applications/v4studio/install.txt b/applications/v4studio/install.txt deleted file mode 100644 index a728b49..0000000 --- a/applications/v4studio/install.txt +++ /dev/null @@ -1,110 +0,0 @@ -What is V4Studio? ------------------- - -This piece of software is an authoring tool to design and encode MPEG-4 content -at large (audio, video, still picture, vector graphics and text). The current -version has no support for audio, video or still picture. But if you edit an -existing mp4 files that contains some media, they will remain in the output mp4. - -This tool was design based on the rendering system of the gpac project but the -GUI is written using wxWindows (www.wxwindows.org). - -The current version allows you to open an mp4 file or a bt file, to edit the -graphical elements (vector graphics, text) of the initial BIFS scene. You can -then save the result to an mp4 file. Editing is very limited for the moment, you -can: -- add nodes within a node depending on the context. -- delete nodes -- change some field values (float, int, string, colours, points) -- move objects. - -Problems: ---------- -Since it is in a version early stage, this software has known bugs (fields list -view, node drag and drop, node deletions) and may have some more unknown ones. - -How to install V4Studio? --------------------------- -I'm using Windows 2000 and I haven't tried it yet on other platforms. Please -report any problem. Only the Debug version has been tested. - -On Windows: -Get the source from the gpac project http://gpac.sourceforge.net - -Compiling: ---------- -Open the GPAC.dsw file. Set the V4Studio project active and build it. It will -build also libgpac.dll. - -The current version uses a hard-coded path to a configuration file GPAC.cfg. -Before compiling, you should change that path to your path. In the file -wxGPACPanel.cpp, change: - strcpy(config_path, "E:\\MesProjets\\gpac\\gpac\\bin\\Debug"); -into: - strcpy(config_path, \\gpac\\bin\\w32_deb"); - -To link, it needs the js32.lib. Place it under gpac/extra_lib/lib/w32_deb. - -To link, you also need some elements from wxWidgets, version 2.5.2. You need to change the path -to the wxWidgets include and library directories, in tools->options, Directories tab -Add to include directories: -\wxWidgets\include -\wxWidgets\contrib\include -\wxWidgets\lib\mswd - -Add to library directories: -\wxWidgets\lib -\wxWidgets\contrib\lib - -The following libs from wxWidgets are required and should be present in V4Studio project linker settings: -wxmsw25d_html.lib wxbase25d.lib wxmsw25d_core.lib wxmsw25d_adv.lib wxbase25d_xml.lib wxexpatd.lib wxmsw25d_xrc.lib -(remove the 'd' for release versions) - - -Once this is done, you should be able to compile V4Studio.exe. - -Running: --------- -To run the tool, you should have a valid GPAC.cfg file. If you don't have the -GPAC.CFG file, here a default content, where you should change ------------------------------------- -[General] -ModulesDirectory=\gpac\bin\Debug\ -CacheDirectory=\gpac\bin\Debug\cache - -[Rendering] -DriverName=gdip_rend -AntiAlias=All - -[Audio] -ForceConfig=yes -NumBuffers=8 -TotalDuration=400 -DriverName=dx_hw - -[FontEngine] -DriverName=gdip_rend -FontDirectory=C:\WINNT\Fonts - -[Video] -DriverName=dx_hw - -[System] -ThreadingPolicy=Free -Priority=normal ------------------------------------------ - -You need also at least the plugin for the Rendering section (here gdip_rend), -the Video section (here dx_hw), the audio section (here dx_hw). So you should -also compile the dll for the 2 projects gdip_rend, and dx_hw. Then put the dll -in the modules Directory. - -To run the tool outside VC++, copy the V4Studio.exe file in a PATH and copy the -rc directory into the same PATH. The program should run without error messages. - -If GPAC has been compiled with ECMAScript support, you will -also have to copy the js32.dll into the execution directory (or any directory in -the machine PATH) - -Other platforms: -To be tested ... \ No newline at end of file diff --git a/applications/v4studio/rc/V4Studio.aps b/applications/v4studio/rc/V4Studio.aps deleted file mode 100644 index 1e237e05be0c95a0c22ebcb899e1ae251689191c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60860 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 diff --git a/applications/v4studio/rc/close.bmp b/applications/v4studio/rc/close.bmp deleted file mode 100644 index aeedd7d54e9f51bb54492b9e584d18140974071b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmZvVF%m){3`Ez_nP2KLES>QN_TD9x{E{PagK#3po&q0bw-PVx3NP>s z4?3aJ9{NvQV#_@ZrBv@-wN@H4w&q+FWUUA(KNz_<+3^mxVr}`Y*v!B@0~;eI%|T;+ WfDi61?iX$A#SqH$V)4tCy{Nx&|3)OM0 zNq)Yntg=xh9>?d*{N;9@OyT!0-tjiv)Cz3AyzP{vxy7<$~OeTT!c7JQf6T89- z%?kmn<${;(P#uFN<0A#FuUo(qgT{&F@ekspii W=d@ZzPG(Cb=QBs}_=7thzxV(viB<;y diff --git a/applications/v4studio/rc/cut.bmp b/applications/v4studio/rc/cut.bmp deleted file mode 100644 index 15554338a01bc4d8f0a501c32237e84200e64583..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmZvU!3}^Q5Cqr6gr}Ba8OD(CvKJo2^+{<|WDB@(K8*2TclNjo+kV075Ef~cCTYMZ z2hQ$)mH}PlY>+FWlp?l4?H9GSBD!~uE%28ISaR-wrPxe$a^ z3z}k}8a(PT6+_I#ss$p5)ly7b@GC~Mg&4(XT5vf7Ssd;QV$6pthFgSe6fzsG63D<5 bM-~CHaVdr=Pty0+l diff --git a/applications/v4studio/rc/group.bmp b/applications/v4studio/rc/group.bmp deleted file mode 100644 index 08175bda244e0f5698a2dc8c3cc322d99fae43ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 310 zcmb`BF%H5o6hmE!txMq)oS+Bj-n%eSq%PUQjk4xu>HAI*V#kU79Y;#Mtn(n_iQeHA zPH@l#l`6cAosoZ$B(_rO1I4P=%8ZNVt=7UpRz%2l;z9o7IR_$ty^UnQ8{HSTz^tNo2jzFSDIDS1`>4%3WFn%sEbh;9Dzh#mcrl&B)MF|PjzEG1#8bCYkwnW$S&yzT zI0A|K5EKSSAWVr`j9DxJ{@z4)PAi)6f)C<+ER3zCllZl6ZI06YaARhYR z2qf5)c<6^Ckl-NVp&yPwg2Oq2emDY&N~6(8#^bR}CKH)Xr!t$(WImtEVzH3raw)6T zO4jSOY&IL&@Aq;z9OQUB%IS2H^Z6{7%SEo&>(_p5({Cz1|DQhIw_VqLw86ekv)fgB zSG8NJ2{my@?|1Ev_Au6d@7mjc+qL}9{9S+iZT+@y4dZQUO>gtR23z~@R*erU+w{BQ EH_2KZCjbBd diff --git a/applications/v4studio/rc/ils2d.bmp b/applications/v4studio/rc/ils2d.bmp deleted file mode 100644 index 1ff4094df7ac0fd67a709cacb6d5d731308fe640..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1334 zcmb`_F|OJ`5P;!%QX)l)o)o3z1oR``0YV*#3(!u(1vmi*Fpa0dqHxOvI04esoB+{t zg2_KNCa+A9wZ6rkUC$1?{`LFgs|@Yqi^!b2A5U-cZ5((L`T2b$+)qupF*pJVA*e7o z0*RWaFgOBTzwTQyt2qcIOm(e={i7G~6a0C)npu*q?B&ukI!4XK* zA5j<_fkgc|g~1U>umG#ua5;S-QJbJJI0A{<7=^(RNYrL2430peHc(-31QNBW3WFn% zAQAOcB|cn1pQz1O7#x8_9f-o<2qfx|6b45iQ3t0mI0A_}OohP_Nbmyn)UH$|FV1Rn+glbo+k{m83Qx9=C0tpgO z4{Fa0C)8&Jx7o2qdb#zrV|DHk0{$E{nxNmdmBARx4Sr*Rt7c zWV_wUZnu;DelN%4QBJ3moX=;uTrP6GUgdVX$>Z^O#4FG@&w1lb|9Wqn*f)nU&Ha9uG7hix-D@UEy0&S%DN%o@hv|u- T!}L(={T&(-e;S$=`tffN_D# zmjC}5fU^IQ0GP`F6vxy86oerp4G2M?EE<5Thf5)gK-h3Cm{PbzfLd@#QCS=S{ogit diff --git a/applications/v4studio/rc/layer2d.bmp b/applications/v4studio/rc/layer2d.bmp deleted file mode 100644 index 9d8e28b8d033c89295d8d97979967d22be1c6b20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 310 zcmY+8K?=hl5Ji8WkU%zVPSF$e0NLj*u4*6~Aqxw=Om?&NX7&Ze*u&8RX)d`!;^`jqkYl0rV2j_xYb?A4MXEQtkD#773+YYggp7@QU|#I!M# vmoc0sZ(vxAUEyDpLhBN96*QFUA3oyK6VfZB?Osx^x+h9O%vZ5`M;@V6Z}e2SNVGQy1r z=gbh$kU?XC@-Eo;1M8Ji9Jtiz`yn};>rw?YIDFp)4{;I3{k~vxvZXG$aiXIYi|={g E3w(AS?EnA( diff --git a/applications/v4studio/rc/movie.bmp b/applications/v4studio/rc/movie.bmp deleted file mode 100644 index 312f6db7612b31a003c9b731103772745f116032..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmZ?rea8R+Wk5;;i20$Ik%0v)Q2``{xFJ{oECM4M7#M(vp`ign0ZAZ};lP0dKpG_R xAB-6O{|B*v7zjZ^AOZ^bIXZvg3Zl_)d6)(m4OIu1N7Dy02QClQ2LP%1FJ%A# diff --git a/applications/v4studio/rc/new.bmp b/applications/v4studio/rc/new.bmp deleted file mode 100644 index d66feb2384ad4c626a078c995c1a3e49af78ec3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmbu2yA6Oa5JQcGL>b0l4tjP;1(ew=nJ8j|<6WY3bU0`GK9aK^RUId`!4(ELX-1{H u>6c`QQqJ8_T9s0iQsQ8(Wab^@`3kuPA_p->w)Xt4Pkz>06 diff --git a/applications/v4studio/rc/open.bmp b/applications/v4studio/rc/open.bmp deleted file mode 100644 index bbf93fe03364e63f3e18a3507a0e85ab8ea2f87d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmXv{u@M3>3=;=;U&0ua+_3>YyQsonW~6N3OvKTr2(k@|B{{YeKb~(CUb3rr5zpcQ zCn>O}mP9XDa6kd~GO1FGG0<95V`X5i$V8neN$dxz4&8XX3!AZr-;ApY^eS-9oTLj~ Y^Hcc9z2|$wrXTtLH=Rc2n(WoWFRhqJ00000 diff --git a/applications/v4studio/rc/orderedgroup.bmp b/applications/v4studio/rc/orderedgroup.bmp deleted file mode 100644 index 9d8e28b8d033c89295d8d97979967d22be1c6b20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 310 zcmY+8K?=hl5Ji8WkU%zVPSF$e0NLj*u4*6~Aqxw=Om?&NX7&Ze*u&8RX)d`!;^`jqkYl0rV2j_xYb?A4MXEQtk$83OZ*I;# co}I%%@f6>ra3+S=gC69}eM%GII+SAI4J;x>B>(^b diff --git a/applications/v4studio/rc/paste_use.bmp b/applications/v4studio/rc/paste_use.bmp deleted file mode 100644 index 066ee7cc989458b85cb51527618433bf21757ab9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmYL?I}So25Jj(viI`VtT!qUphJ?znl~;)+CGNmixdnS0R^%4&4461@@0m{+&XpI>trgm!^{dt_LmX>iDJ4&YS&G!bl@h&=!QCID qhCceRU6yBS@kgJS^Xz0SrR3!78)syru}pf=XYX6u(44!I^!Nh0mPVNX diff --git a/applications/v4studio/rc/preview.bmp b/applications/v4studio/rc/preview.bmp deleted file mode 100644 index da1f4dbc4be6c2dd8fb9d7cb71cc48a4a7c139ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmZvVu?@p83pv2yNo4mlT?N_pr2ISnd1NHDM5O^cFcMc59&^> z)PfrwsOeYM05)2ipmU4fJIss+o(=cdQCu+!%TlZiKDH!a!aP2;C|UGpLD9M;zmsLJ XIp;lzIUm!ckI6HO{IjaYcZ_-fA4^nl diff --git a/applications/v4studio/rc/print.bmp b/applications/v4studio/rc/print.bmp deleted file mode 100644 index 00319b55bb23c3c69cc051144d80e5275747c53e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmZur!3_d23^Ni^o@EUFY`~vgA|YX<`*bfpod|VizM>j+f}Fx~Q7! zgtHKM7yg3|DAD^Sp<0YF#C}+nSj(MC$5#Ss27*aN<{l9dp7pzrGpff7&!z1W7RjCyO8{ z`oYN}NQ!=WvIvr*7o04Dr07j1iy$dPx4w))QgkwtMUWJo;A9abMJGL31WC~!GFb#k z(H}Qi1W927yRWT>F)6wTlSPmeU6{!tNQy4jWDz7q7jUu&lA?<`Sp-R8A^CJBvGp_- zUHr)+NQyp?$s$OKKBUPaNQyqV$s$OKKFrA?ND42=r>oML7~~^PkQ8pnr%$M>(wWrOJuDw_f~2s3e8dTo!lLpKCrAn#$w!Fae}1ic6xd`&d$!pZnqoz{eBz{hjDRnF)lAJ$JN!L; ve?J}`9>(M2<9K>{8qd$qJQ3^NitoWUKaQYXHtaK{cvyw!_%p*Ri9bz(b-vmXx}r)(2faS - - - - - - - Create a new document - - - - Open an existing document - - - - Save the active document - - - - - Quit the application; prompts to save documents - - - - - - - Undo the last action - - - - Redo the previously undone action - - - - - Cut the selection and put it on the Clipboard - - - - Copy the selection and put it on the Clipboard - - - - Insert Clipboard contents - - - - Delete the selection - - - - - - - Show or hide the Scene Tree - - - - Show or hide the GF_Route View - - - - Show or hide the Field View - - - - - - - Display program information, version number and copyright - - - - diff --git a/applications/v4studio/rc/rg.bmp b/applications/v4studio/rc/rg.bmp deleted file mode 100644 index 5bfe4f1c1efcc826e548fc6b50bdc740fd827d15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 774 zcmZ?rWn*Rl12Z700mK48%n!tj3=%++f#CuZ1A`DZ1cL>D#61RuvkV46w3opFh}JR$ zVj_qXL>WXqT;&{wL`(!R0jLIUGDHNZvWKA%69L8HS|D}-xp2i*3@ykAq8*|ItKvk4 zxyT5p7flP?aG(@Wr6YV3`7rsq)3!X>4ws(){6V0MX5FKAjcylGXqN-n#XsS=YhW0WogZT{L^_i_GT%*k@+ph E1NJ~MtpET3 diff --git a/applications/v4studio/rc/shape.bmp b/applications/v4studio/rc/shape.bmp deleted file mode 100644 index 8672ae8513413fe082b311db96063c9170b1e90b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 310 zcmY+8F%AMD5JiW?Zkxr{3wQz#VDDYDaZPCG@CqKoik53x;hPzva2&dAeKYfB?GRw>S&yH;*V|>V(1Uu$ zM|{A8?Wkr2pT=hKP1%fYIk$mIv{DMA7HV{>RSDCCD5>iX|H;fH@#z`Lk>^m$j`rTU iR_D%N-&_Ya?(2RV|M;@r&wG*6;;ui5C*UV5An`Y#=2|-d diff --git a/applications/v4studio/rc/text.bmp b/applications/v4studio/rc/text.bmp deleted file mode 100644 index 2decce39882ecc43b1e9a7ff73e1bfc49222d99d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 298 zcmYk0%?&~^41@h7q<7%J&lHF;xU)-65>JF+u@$Sdh|5JU$lQVNJQ3!n}6e%=pgD_<}*2+Yz5YBOr`1t>vyt3|(LMK@8j3+#3B&Dlo ygm>;xkr)m_l%iTMX5l^3fyO9s)fg6#}AJ2s6x1u~4 z9D#%oR2UqAM7^jmI0A{9tS~qNiCR!$a0C*yiNfFrB#8FaXdQt>C8IDn0*OjcVQ>Tz zm9)a(2qfx56b45iQ6Hx;I06YaV0Y`Q(*_cC2nvHEkf?)E7#x8_9hSo22qfwN6$VEj zQHQE9I06Y4BA?2{`x>-~I(&t}5lGa9C=8B3qAp2ca0C){aSDSYkf_U47#x8F6Ue7d zr80@WCT(51!r%xb>PJu*9Dzjr914RYkfTzG~`1ZjzEF|@~IoDQ>jd{ue?k? z#Nh}eSb%(p!x2cZDESbFBamPt@*xgKAi?HrK^%@iqRL<}kl}DBqtQsln^%PNzTX^^5+eru$cUk=LuR z$n$0YJ9}UDE0rHzw{DtMg&BT2JpJt-M81iv*KO0Z+w<_cd1(5=1SbDnHMi2On7{2_ unB8sL=Jr5;-F44W$!u2-!us^PSC+0o!+O - -#endif - diff --git a/applications/v4studio/treeIcon1.xpm b/applications/v4studio/treeIcon1.xpm deleted file mode 100644 index 0263fad..0000000 --- a/applications/v4studio/treeIcon1.xpm +++ /dev/null @@ -1,41 +0,0 @@ -/* XPM */ -static char *icon1_xpm[] = { -/* width height num_colors chars_per_pixel */ -" 32 32 2 1", -/* colors */ -". c #000000", -"# c #ffffff", -/* pixels */ -"################################", -"################################", -"####................############", -"####................############", -"####..############....##########", -"####..############....##########", -"####..##..##..####..##..########", -"####..##..##..####..##..########", -"####..############........######", -"####..############........######", -"####..##..##..##########..######", -"####..##..##..##########..######", -"####..##################..######", -"###...##################..######", -"####..##..##..##..##..##..######", -"####..##..##..##..##..##..######", -"####..##################..######", -"####..##################..######", -"####..##..##..##..##..##..######", -"####..##..##..##..##..##..######", -"####..##################..######", -"####..##################..######", -"####..##..##..##..##..##..######", -"####..##..##..##..##..##..######", -"####..##################..######", -"####..##################..######", -"####......................######", -"####......................######", -"################################", -"################################", -"################################", -"################################" -}; diff --git a/applications/v4studio/treeIcon2.xpm b/applications/v4studio/treeIcon2.xpm deleted file mode 100644 index d3d76ec..0000000 --- a/applications/v4studio/treeIcon2.xpm +++ /dev/null @@ -1,42 +0,0 @@ -/* XPM */ -static char *icon2_xpm[] = { -/* width height num_colors chars_per_pixel */ -" 32 32 3 1", -/* colors */ -". c #000000", -"# c #ff0000", -"a c None", -/* pixels */ -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaa................aaaaaaaaaaaa", -"aaaa................aaaaaaaaaaaa", -"aaaa..############....aaaaaaaaaa", -"aaaa..############....aaaaaaaaaa", -"aaaa..##..##..####..aa..aaaaaaaa", -"aaaa..##..##..####..aa..aaaaaaaa", -"aaaa..############........aaaaaa", -"aaaa..############........aaaaaa", -"aaaa..##..##..##########..aaaaaa", -"aaaa..##..##..##########..aaaaaa", -"aaaa..##################..aaaaaa", -"aaaa..##################..aaaaaa", -"aaaa..##..##..##..##..##..aaaaaa", -"aaaa..##..##..##..##..##..aaaaaa", -"aaaa..##################..aaaaaa", -"aaaa..##################..aaaaaa", -"aaaa..##..##..##..##..##..aaaaaa", -"aaaa..##..##..##..##..##..aaaaaa", -"aaaa..##################..aaaaaa", -"aaaa..##################..aaaaaa", -"aaaa..##..##..##..##..##..aaaaaa", -"aaaa..##..##..##..##..##..aaaaaa", -"aaaa..##################..aaaaaa", -"aaaa..##################..aaaaaa", -"aaaa......................aaaaaa", -"aaaa......................aaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" -}; diff --git a/applications/v4studio/treeIcon3.xpm b/applications/v4studio/treeIcon3.xpm deleted file mode 100644 index 0dba5be..0000000 --- a/applications/v4studio/treeIcon3.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *icon3_xpm[] = { -/* width height num_colors chars_per_pixel */ -" 32 32 5 1", -/* colors */ -". c #000000", -"# c #c0c0c0", -"a c #808080", -"b c #ffff00", -"c c None", -/* pixels */ -"cccccccccccccccccccccccccccccccc", -"cccccccccccccccccccccccccccccccc", -"ccccccaaaaaaaaaacccccccccccccccc", -"ccccccaaaaaaaaaacccccccccccccccc", -"ccccaabb##bb##bbaacccccccccccccc", -"ccccaabb##bb##bbaacccccccccccccc", -"ccaabb##bb##bb##bbaaaaaaaaaaaacc", -"ccaabb##bb##bb##bbaaaaaaaaaaaacc", -"ccaaccccccccccccccccccccccccaa..", -"ccaaccccccccccccccccccccccccaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaaaaaaaaaaaaaaaaaaaaaaaaaaa..", -"ccaaaaaaaaaaaaaaaaaaaaaaaaaaaa..", -"cccc............................", -"cccc............................", -"cccccccccccccccccccccccccccccccc", -"cccccccccccccccccccccccccccccccc", -"cccccccccccccccccccccccccccccccc", -"cccccccccccccccccccccccccccccccc" -}; diff --git a/applications/v4studio/treeIcon4.xpm b/applications/v4studio/treeIcon4.xpm deleted file mode 100644 index f4cd561..0000000 --- a/applications/v4studio/treeIcon4.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *icon4_xpm[] = { -/* width height num_colors chars_per_pixel */ -" 32 32 5 1", -/* colors */ -". c #000000", -"# c #c0c0c0", -"a c #808080", -"b c #ff0000", -"c c #ffffff", -/* pixels */ -"cccccccccccccccccccccccccccccccc", -"cccccccccccccccccccccccccccccccc", -"ccccccaaaaaaaaaacccccccccccccccc", -"ccccccaaaaaaaaaacccccccccccccccc", -"ccccaabb##bb##bbaacccccccccccccc", -"ccccaabb##bb##bbaacccccccccccccc", -"ccaabb##bb##bb##bbaaaaaaaaaaaacc", -"ccaabb##bb##bb##bbaaaaaaaaaaaacc", -"ccaaccccccccccccccccccccccccaa..", -"ccaaccccccccccccccccccccccccaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaacc##bb##bb##bb##bb##bb##aa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaccbb##bb##bb##bb##bb##bbaa..", -"ccaaaaaaaaaaaaaaaaaaaaaaaaaaaa..", -"ccaaaaaaaaaaaaaaaaaaaaaaaaaaaa..", -"cccc............................", -"cccc............................", -"cccccccccccccccccccccccccccccccc", -"cccccccccccccccccccccccccccccccc", -"cccccccccccccccccccccccccccccccc", -"cccccccccccccccccccccccccccccccc" -}; diff --git a/applications/v4studio/treeIcon5.xpm b/applications/v4studio/treeIcon5.xpm deleted file mode 100644 index 63820ef..0000000 --- a/applications/v4studio/treeIcon5.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *icon5_xpm[] = { -/* width height num_colors chars_per_pixel */ -" 32 32 4 1", -/* colors */ -". c #000000", -"# c #808000", -"a c None", -"b c #ffff00", -/* pixels */ -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aa..........aaaaaaaaaaaaaaaaaaaa", -"aa..........aaaaaaaaaaaaaaaaaaaa", -"aa..bbbbbb................aaaaaa", -"aa..bbbbbb................aaaaaa", -"aa..bbbbbbbbbbbbbbbbbbbb..aaaaaa", -"aa..bbbbbbbbbbbbbbbbbbbb..aaaaaa", -"aa..bbbbbbbbbbbbbbbbbbbb..aaaaaa", -"aa..bbbbbbbbbbbbbbbbbbbb..aaaaaa", -"aa..bbbb......................aa", -"aa..bbbb......................aa", -"aa..bbb.####################..aa", -"aa..bbb.####################..aa", -"aa..bb..####################.aaa", -"aa..bb..####################.aaa", -"aa..b.####################..aaaa", -"aa..b.####################..aaaa", -"aa....####################.aaaaa", -"aa....####################.aaaaa", -"aa..####################..aaaaaa", -"aa..####################..aaaaaa", -"aa......................aaaaaaaa", -"aa......................aaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" -}; diff --git a/applications/v4studio/wxGPACPanel.cpp b/applications/v4studio/wxGPACPanel.cpp deleted file mode 100644 index 1e36858..0000000 --- a/applications/v4studio/wxGPACPanel.cpp +++ /dev/null @@ -1,290 +0,0 @@ -#include "safe_include.h" -#include -#include - -#include "wx/wxprec.h" - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include "wxGPACPanel.h" -#include "V4StudioFrame.h" -#include "V4StudioApp.h" -#include "V4Service.h" - - -bool GPACInit(void *application, GF_Terminal **term, GF_User *user, bool quiet); - -wxGPACPanel::wxGPACPanel(V4SceneManager *parent, const char *path) -{ - this->parent = parent; - m_term = NULL; - m_pService = NULL; - - // Initializes the MPEG-4 terminal - GPACInit(this, &m_term, &m_user, true); - if (!m_term) return; - - // Setting all the variables needed for picking of objects. - m_iDragging = 0; - m_transformMode = 0; - dragX = dragY = 0; - picked = NULL; - - if (path) { - m_pService = new V4Service(path); - gf_term_attach_service(m_term, m_pService->GetServiceInterface()); - } -} - -wxGPACPanel::~wxGPACPanel() -{ - if (m_pService) delete m_pService; - if (m_term) gf_term_del(m_term); - if (m_user.modules) gf_modules_del(m_user.modules); - if (m_user.config) gf_cfg_del(m_user.config); -} - - -Bool V4S_EventProc(void *par, GF_Event *evt) -{ - wxGPACPanel *panel = (wxGPACPanel *)par; - if (!panel->GetMPEG4Terminal()) return 0; - - switch (evt->type) { - case GF_EVENT_REFRESH: - gf_term_set_option(panel->GetMPEG4Terminal(), GF_OPT_REFRESH, 0); - break; - case GF_EVENT_SCENE_SIZE: - case GF_EVENT_SIZE: - gf_sc_set_size(panel->GetSceneCompositor(), evt->size.width, evt->size.height); - panel->Update(); - break; - case GF_EVENT_MOUSEDOWN: - if (evt->mouse.button==GF_MOUSE_LEFT) { - panel->picked = gf_sc_pick_node(panel->GetSceneCompositor(), evt->mouse.x, evt->mouse.y); - panel->m_iDragging ++; - if (panel->picked) { - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->SetSelectedItem(panel->picked); - panel->dragX = evt->mouse.x; - panel->dragY = evt->mouse.y; - panel->m_transformMode = 0; - } - } - else if (evt->mouse.button==GF_MOUSE_MIDDLE) { - panel->m_iDragging ++; - panel->picked = gf_sc_pick_node(panel->GetSceneCompositor(), evt->mouse.x, evt->mouse.y); - if (panel->picked) { - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->SetSelectedItem(panel->picked); - panel->dragX = evt->mouse.x; - panel->dragY = evt->mouse.y; - panel->m_transformMode = 2; - } - } - else if (evt->mouse.button==GF_MOUSE_RIGHT) { - panel->m_iDragging ++; - panel->picked = gf_sc_pick_node(panel->GetSceneCompositor(), evt->mouse.x, evt->mouse.y); - if (panel->picked) { - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->SetSelectedItem(panel->picked); - panel->dragX = evt->mouse.x; - panel->dragY = evt->mouse.y; - panel->m_transformMode = 1; - } - } - break; - case GF_EVENT_MOUSEUP: - if (evt->mouse.button==GF_MOUSE_LEFT) { - panel->m_iDragging --; - if (panel->picked) { - int dX = evt->mouse.x - panel->dragX; - int dY = evt->mouse.y - panel->dragY; - panel->dragX = evt->mouse.x; - panel->dragY = evt->mouse.y; - wxString pos; - pos << dX; - pos << ','; - pos << dY; - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->Translate(dX,dY); - panel->GetV4SceneManager()->GetV4StudioFrame()->GetStatusBar()->SetStatusText(pos); - } - } - else if (evt->mouse.button==GF_MOUSE_MIDDLE) { - panel->m_iDragging --; - if (panel->picked) { - int dX = evt->mouse.x - panel->dragX; - int dY = evt->mouse.y - panel->dragY; - panel->dragX = evt->mouse.x; - panel->dragY = evt->mouse.y; - wxString pos; - pos << dX; - pos << ','; - pos << dY; - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->Rotate(dX,dY); - panel->GetV4SceneManager()->GetV4StudioFrame()->GetStatusBar()->SetStatusText(pos); - } - } - else if (evt->mouse.button==GF_MOUSE_RIGHT) { - panel->m_iDragging --; - if (panel->picked) { - int dX = evt->mouse.x - panel->dragX; - int dY = evt->mouse.y - panel->dragY; - panel->dragX = evt->mouse.x; - panel->dragY = evt->mouse.y; - wxString pos; - pos << dX; - pos << ','; - pos << dY; - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->Scale(dX,dY); - panel->GetV4SceneManager()->GetV4StudioFrame()->GetStatusBar()->SetStatusText(pos); - } - } - break; - case GF_EVENT_MOUSEMOVE: - { - wxString pos; - if (panel->picked && panel->m_iDragging) { - int dX = evt->mouse.x - panel->dragX; - int dY = evt->mouse.y - panel->dragY; - panel->dragX = evt->mouse.x; - panel->dragY = evt->mouse.y; - pos << dX; - pos << ','; - pos << dY; - switch (panel->m_transformMode) { - case 0: - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->Translate(dX,dY); - break; - case 1: - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->Scale(dX,dY); - break; - case 2: - panel->GetV4SceneManager()->GetV4StudioFrame()->GetTreeView()->Rotate(dX,dY); - break; - } - } else { - pos << evt->mouse.x; - pos << ','; - pos << evt->mouse.y; - } - panel->GetV4SceneManager()->GetV4StudioFrame()->GetStatusBar()->SetStatusText(pos); - } - break; - case GF_EVENT_QUIT: - panel->GetV4SceneManager()->GetV4StudioFrame()->Close(TRUE); - break; - } - return 0; -} - -void wxGPACPanel::Update() -{ - if (m_term) { - //gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); - gf_sc_invalidate(m_term->compositor, NULL); - gf_sc_draw_frame(m_term->compositor); - } -} - -bool GPACInit(void *application, GF_Terminal **term, GF_User *user, bool quiet) -{ - memset(user, 0, sizeof(GF_User)); - - /*locate exec dir for cfg file*/ - wxPathList pathList; - wxString currentDir(wxGetCwd()); - wxString abs_gpac_path = ""; - const char *gpac_cfg; - - if (!quiet) ::wxLogMessage("Looking for GPAC configuration file"); - -#if defined(__WXMAC__) && !defined(__DARWIN__) - // On Mac, the current directory is the relevant one when the application starts. - abs_gpac_path = wxGetCwd(); - gpac_cfg = "GPAC.cfg"; -#else - -#ifdef WIN32 - V4StudioApp &app = wxGetApp(); - gpac_cfg = "GPAC.cfg"; - /*locate exe*/ - if (wxIsAbsolutePath(app.argv[0])) { - abs_gpac_path = wxPathOnly(app.argv[0]); - } else { - if (currentDir.Last() != wxFILE_SEP_PATH) currentDir += wxFILE_SEP_PATH; - abs_gpac_path = currentDir + app.argv[0]; - if (wxFileExists(abs_gpac_path)) { - abs_gpac_path = wxPathOnly(abs_gpac_path); - } else { - abs_gpac_path = ""; - pathList.AddEnvList(wxT("PATH")); - abs_gpac_path = pathList.FindAbsoluteValidPath(app.argv[0]); - if (!abs_gpac_path.IsEmpty()) { - abs_gpac_path = wxPathOnly(abs_gpac_path); - } else { - /*ask user*/ - wxDirDialog dlg(NULL, "Locate GPAC config file directory"); - if ( dlg.ShowModal() != wxID_OK ) return 0; - abs_gpac_path = dlg.GetPath(); - } - } - } -#else - gpac_cfg = ".gpacrc"; - char *cfg_dir = getenv("HOME"); - if (cfg_dir) { - abs_gpac_path = cfg_dir; - } else { - /*ask user*/ - wxDirDialog dlg(NULL, "Locate GPAC config file directory"); - if ( dlg.ShowModal() != wxID_OK ) return 0; - abs_gpac_path = dlg.GetPath(); - } - -#endif - -#endif - - /*load config*/ - Bool first_launch = 0; - user->config = gf_cfg_init(NULL, &first_launch); - - if (!user->config) { - wxMessageDialog(NULL, "Cannot create GPAC config file", "Init error", wxOK).ShowModal(); - } - if (!quiet) ::wxLogMessage("GPAC configuration file opened - looking for modules"); - const char *str = gf_cfg_get_key(user->config, "General", "ModulesDirectory"); - user->modules = gf_modules_new(str, user->config); - - if (! gf_modules_get_count(user->modules) ) { - wxMessageDialog(NULL, "No modules available - system cannot work", "Fatal Error", wxOK).ShowModal(); - gf_modules_del(user->modules); - gf_cfg_del(user->config); - return 0; - } - - if (!quiet) ::wxLogMessage("%d modules found:", gf_modules_get_count(user->modules)); - for (u32 i=0; imodules); i++) { - if (!quiet) ::wxLogMessage("\t%s", gf_modules_get_file_name(user->modules, i)); - } - - if (!quiet) ::wxLogMessage("Starting GPAC Terminal"); - /*now load terminal*/ - user->opaque = application; - user->EventProc = V4S_EventProc; -// user->os_window_handler = ((wxGPACPanel *)application)->GetV4SceneManager()->GetV4StudioFrame()->GetHandle(); - - // Forces the renderer to not use a thread and do the rendering by itfe - gf_cfg_set_key(user->config, "Systems", "NoVisualThread", "No"); - - *term = gf_term_new(user); - if (!*term) { - wxMessageDialog(NULL, "Fatal Error", "Cannot load GPAC Terminal", wxOK).ShowModal(); - return 0; - } else { - if (!quiet) ::wxLogMessage("GPAC Terminal started"); - } - - return 1; -} - diff --git a/applications/v4studio/wxGPACPanel.h b/applications/v4studio/wxGPACPanel.h deleted file mode 100644 index ea46034..0000000 --- a/applications/v4studio/wxGPACPanel.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _GPACPANEL_H -#define _GPACPANEL_H - - -#include "safe_include.h" -#include -#include -/*for service connection...*/ -#include - -class V4SceneManager; -class V4Service; - -class wxGPACPanel -{ - -public : - // Constructor / Desctructor - wxGPACPanel(V4SceneManager *parent, const char *path); - ~wxGPACPanel(); - - // Access to private members - GF_Terminal *GetMPEG4Terminal() { return m_term; } - GF_Compositor *GetSceneCompositor() { return m_term->compositor; } - V4SceneManager *GetV4SceneManager() { return parent; } - // - void Update(); - - // Variables used for drag, drop, move, ... picking ... - s32 m_iDragging; - u32 m_transformMode; // 0 Move, 1 Scale, 2 Rotate - GF_Node *picked; - u32 dragX, dragY; - -private: - void TranslateCoordinates(long x, long y, int &sceneX, int &sceneY); - - V4SceneManager *parent; - - GF_Terminal *m_term; - GF_User m_user; - - V4Service *m_pService; -}; - -#endif diff --git a/configure b/configure index feca36b..a117a4a 100755 --- a/configure +++ b/configure @@ -292,6 +292,8 @@ for opt do case "$opt" in --prefix=*) prefix=`echo $opt | cut -d '=' -f 2` ;; + --libdir=*) libdir=`echo $opt | cut -d '=' -f 2` + ;; --mandir=*) mandir=`echo $opt | cut -d '=' -f 2` ;; --source-path=*) source_path=`echo $opt | cut -d '=' -f 2` @@ -340,9 +342,6 @@ case "$cpu" in if [ x"$canon_arch" = x"x86_64" -o x"$canon_arch" = x"amd64" ]; then if [ -z "`echo $CFLAGS | grep -- -m32`" ]; then cpu="x86_64" - if test "$linux" = "yes" ; then - libdir="lib64" - fi want_pic="yes" fi fi @@ -355,7 +354,6 @@ case "$cpu" in ;; ppc64) cpu="powerpc" - libdir="lib64" ;; "Power Macintosh"|ppc) cpu="powerpc" -- 2.30.2